代码简洁之道—Stream API

  JDK8起新添加的Stream API 把真正的函数式编程风格引入到Java中。以一种声明的方式处理数据,从而写出高效率、干净、简洁的代码。

  Stream特性

  1、不是数据结构,没有内部存储
  2、不支持索引访问
  3、延迟计算
  4、支持并行操作
  5、容易生成数组或集合
  6、支持过滤,查找,转换,汇总,聚合等操作,代码优雅
  
  Stream API优势
  1、告别for循环
  2、多核友好操作
 
  
  Stream运行机制
  Stream分为源source,中间操作,终止操作
  流的源可以是一个数组,一个集合,一个生成器方法,一个I/O通道等等
  一个流可以有0个或多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作
  Stream只有遇到终止操作,源才开始执行遍历操作
  
  Stream常用函数
  创建:
  通过数组
  通过集合
  通过Stream.generate
  通过Stream.iterate
  通过其他API
  注:一般来说,都是对集合和数组直接进行流操作,很少的场合才需要自己生成流
 
  中间操作:
  过滤filter
  去重distinct
  排序sorted
  截取limit,skip
  转换map,flatMap
  其他peek
 
  终止操作:
  循环forEach
  计算min,max,count,average
  匹配anyMatch,allMatch,noneMatch,findFirst,findAny
  汇聚reduce
  收集器toArray collect
  
  Stream API实操
   Stream创建
/**
     * 数组遍历
     */
    static void seqT(){
        String[] strs = {"a","b","c","d","e"};
        //将数组转成流
        Stream<String> streamStr = Stream.of(strs);
        //循环打印数组
        streamStr.forEach(System.out::println);

        Stream.of(strs).forEach(System.out::println);
    }
/**
     * 集合遍历
     */
    static void listT(){
        List<Integer> list = Arrays.asList(4,3,5,6,2,1);
        list.stream().forEach(System.out::println);
    }
/**
     * 利用流直接生成和操作元素
     */
    static void streamT(){
        //生成5个1
        Stream.generate(()->1).limit(5).forEach(System.out::println);
    }
/**
     * 利用迭代器操作元素
     */
    static void iterateT(){
        Stream.iterate(1,x->x+1).limit(10).forEach(System.out::println);
    }
/**
     * 字符串的流操作
     */
    static void stringT(){
        String str = "fuckyou";
        str.chars().mapToObj(item->(char)item).forEach(System.out::println);
    }

  Stream中间操作:中间操作的函数调用,基本都是返回的Stream对象

  filter()筛选过滤

/**
     * 对数组或集合做元素筛选取值
     * filter()
     */
    static void filterT(){
        Arrays.asList(1,2,3,4,5).stream()
                .filter(x->x%2!=0).forEach(System.out::println);
    }
/**
     * 求集合中1,2,3...100的和
     * filter()
     */
    static void sumT(){
        int sum = Stream.iterate(1, x -> x + 1).limit(100).mapToInt(x -> x).sum();
        System.out.println(sum);
    }

  count()统计

/**
     * 求集合中1,2,3...100偶数的个数
     * count()
     */
    static void oushuT(){
        long count = Stream.iterate(1, x -> x + 1).limit(10)
                .filter(x -> x % 2 == 0).count();
        System.out.println(count);
    }

  max(),min()最大最小值

/**
     * 求集合中的最大,最小值
     * max(),min()
     */
    static void maxminT(){
        Integer max = Stream.iterate(1, x -> x + 1).limit(10)
                .max((a, b) -> a - b).get();

        Integer min = Stream.iterate(1, x -> x + 1).limit(10)
                .min((a, b) -> a - b).get();

        System.out.println(max);
        System.out.println(min);
    }

  findAny()查找任意元素

/**
     * 从集合中找出符合条件的第一个元素
     * findany()
     */
    static void findanyT(){
        System.out.println(Stream.iterate(1, x -> x + 1).limit(10)
                .filter(x->x>4).findAny().get());
    }

    Stream不遇到终止操作,不会执行任何中间操作

/**
     * Stream不遇到终止操作,不会执行任何中间操作
     * 如下例子不会打印"中间操作打印"
     */
    static void nofinT(){
        Stream.iterate(1,x->x+1).limit(5).filter(n->{
            return n>3;
        }).forEach(System.out::println);

        Stream<Integer> intStream = Stream.iterate(1, x -> x + 1).limit(3).filter(n -> {
            System.out.println("中间操作打印");
            return n > 3;
        });
        System.out.println(intStream);
    }

  sorted()排序操作

/**
     * 对集合的排序操作
     * sorted();
     */
    static void sortT(){
        Integer min = Stream.iterate(1, x -> x + 1).limit(10)
                .sorted().findFirst().get();
        System.out.println(min);

        Integer max = Stream.iterate(1, x -> x + 1).limit(10)
                .sorted((a, b) -> b - a).findFirst().get();
        System.out.println(max);

        Arrays.asList("c","c++","python","go","java").stream()
                .sorted().forEach(System.out::println);

        System.out.println();

        Arrays.asList("c","c++","python","go","java").stream()
                .sorted((a,b)->a.length()-b.length()).forEach(System.out::println);
    }

  collect()对中间操作过程返回

/**
     * 对Stream的中间操作过程返回一个集合
     * collect()
     */
    static void collectT(){
        List<Integer> collect = Stream.iterate(1, x -> x + 1).limit(10)
                .filter(x -> x > 5).collect(Collectors.toList());
        collect.forEach(System.out::println);
    }

  flatMap()对集合流的操作

/**
     * 对集合做复制操作
     * flatMap()
     * Collections.nCopies(times,e).stream()
     * times—次数
     */
    static void copyT(){
        Stream.iterate(0, x -> x + 2).limit(3)
                .flatMap(e -> Stream.of(e, e)).forEach(System.out::print);

        System.out.println();

        Stream.iterate(0, x -> x + 2).limit(3)
                .flatMap(e-> Collections.nCopies(3,e).stream())
                .forEach(System.out::print);
    }

  distinct()去重操作

/**
     * 对集合做去重操作
     * distinct()
     * Collectors.toSet()
     */
    static void distinctT(){
        Stream.iterate(0, x -> x + 2).limit(3)
                .flatMap(e-> Collections.nCopies(3,e).stream())
                .distinct().forEach(System.out::println);

        Stream.iterate(0, x -> x + 2).limit(3)
                .flatMap(e-> Collections.nCopies(3,e).stream())
                .collect(Collectors.toSet()).forEach(System.out::println);
    }

  skip()跳跃操作

/**
     * 跳跃操作,打印20-30
     * skip()
     */
    static void skipT(){
        Stream.iterate(20, x -> x + 1).limit(11).forEach(System.out::println);

        System.out.println();

        Stream.iterate(1, x -> x + 1).limit(40)
                .skip(19).limit(10).forEach(System.out::println);
    }

  mapToInt() 集合类型转换

/**
     * 批量String转Integer
     */
    static void strs2intT(){
        String str = "10,20,66,88";
        Stream.of(str.split(",")).mapToInt(x->Integer.valueOf(x)+1)
                .forEach(System.out::println);

        System.out.println();

        Stream.of(str.split(",")).map(x->Integer.valueOf(x))
                .mapToInt(x->x+1).forEach(System.out::println);

        System.out.println();

        Stream.of(str.split(",")).mapToInt(Integer::valueOf)
                .forEach(System.out::println);
    }

  map()集合对象操作

/**
     * Stream的对象操作
     */
    static void objT(){
        String str = "dog,cat,monkey,fish";
        Stream.of(str.split(",")).map(x->new Person(x,12))
                .map(x->x.getName()).forEach(System.out::println);
    }

  peek()流操作中间步骤

/**
     * 打印数值的同时计算出结果
     * peek();
     */
    static void midprintT(){
        String str = "1,2,3,4,5,6,7,8,9,10";
        int sum = Stream.of(str.split(",")).peek(System.out::println)
                .mapToInt(Integer::valueOf).sum();
        System.out.println(sum);
    }

  allMatch(),anyMatch()表达式匹配

/**
     * 表达式匹配
     * allMatch()
     * anyMatch()
     */
    static void matchT(){
        String str = "cat,dog,fish,tom";
        //全部匹配
        System.out.println(Stream.of(str.split(","))
                .allMatch(x -> x.length() == 3));

        //部分匹配
        System.out.println(Stream.of(str.split(","))
                .anyMatch(x -> x.length() == 3));
    }

  对集合取并集,交集,合集,合并集合,差集操作

class Person{

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
/**
     * flatmap取并集,交集,合集,合并集合,差集操作
     * map操作
     */
    static void flatmap1T(){
        //交集
        Map<String,Person> personMap1 = new HashMap<String,Person>(){
            {
                put("1",new Person("cat",11));
                put("2",new Person("dog",12));
                put("3",new Person("cow",13));
            }
        };

        Map<String,Person> personMap2 = new HashMap<String,Person>(){
            {
                put("1",new Person("cat",23));
                put("4",new Person("bird",14));
                put("5",new Person("bird",15));
            }
        };

        //取交集
        Map map1 = personMap1.entrySet().stream().filter(e->personMap2.containsKey(e.getKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        System.out.println("交集=="+map1);

        //并集并解决Duplicate key
        Map map2 = Stream.of(personMap1.entrySet(),personMap2.entrySet())
                .flatMap(Collection::stream).distinct()
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(value1,value2)->value1));
        System.out.println("并集1=="+map2);

        //根据对象属性取并集并解决Duplicate key
        Map map3 = Stream.of(personMap1.entrySet(),personMap2.entrySet())
                .flatMap(Collection::stream).filter(distinctByKey(e->e.getValue().getName()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(value1,value2)->value1));
        System.out.println("并集2=="+map3);

        //差集
        Map map4 = personMap1.entrySet().stream().filter(e->!personMap2.containsKey(e.getKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        System.out.println("差集=="+map4);
    }

    //元素去重
    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
/**
     * flatmap取并集,交集,合集,合并集合,差集操作
     * list操作
     */
    static void flatmap3T(){
        Map<String,Person> personMap1 = new HashMap<String,Person>(){
            {
                put("1",new Person("fuck",11));
                put("2",new Person("dog",12));
            }
        };

        Map<String,Person> personMap2 = new HashMap<String,Person>(){
            {
                put("3",new Person("cat",23));
            }
        };
        List<Map<String,Person>> list1 = new ArrayList<Map<String,Person>>(){
            {
                add(personMap1);
                add(personMap2);
            }
        };

        Map<String,Person> personMap3 = new HashMap<String,Person>(){
            {
                put("1",new Person("king",11));
                put("4",new Person("fish",12));
            }
        };

        Map<String,Person> personMap4 = new HashMap<String,Person>(){
            {
                put("5",new Person("cow",23));
            }
        };

        List<Map<String,Person>> list2 = new ArrayList<Map<String,Person>>(){
            {
                add(personMap3);
                add(personMap4);
            }
        };

        //交集
        list1.stream().map(Map::entrySet).flatMap(Set::stream).filter(e->{
            return list2.stream().map(Map::entrySet).flatMap(Set::stream)
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
                    .containsKey(e.getKey());
        }).forEach(k->System.out.println(k.getValue().getName()));

        //并集,合并到一个list
        List merge = Stream.of(list1,list2).flatMap(Collection::stream).distinct()
                .collect(Collectors.toList());
        merge.forEach(System.out::println);

        //差集 = list1 - 交集
        list1.stream().map(Map::entrySet).flatMap(Set::stream).filter(e->{
            return !list2.stream().map(Map::entrySet).flatMap(Set::stream)
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
                    .containsKey(e.getKey());
        }).forEach(k->System.out.println(k.getValue().getName()));
    }

  集合间根据关联关系进行关联操作

class Consumer{

    private String userid;
    private String username;
    private String address;

    public Consumer(String userid, String username, String address) {
        this.userid = userid;
        this.username = username;
        this.address = address;
    }

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}

class Product{

    private String userid;
    private String prodid;
    private String prodname;
    private String money;

    public Product(String userid, String prodid, String prodname, String money) {
        this.userid = userid;
        this.prodid = prodid;
        this.prodname = prodname;
        this.money = money;
    }

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getProdid() {
        return prodid;
    }

    public void setProdid(String prodid) {
        this.prodid = prodid;
    }

    public String getProdname() {
        return prodname;
    }

    public void setProdname(String prodname) {
        this.prodname = prodname;
    }

    public String getMoney() {
        return money;
    }

    public void setMoney(String money) {
        this.money = money;
    }
}
/**
     * 集合间根据关联关系进行关联操作
     * 将顾客和商品的集合根据顾客id关联查询汇集到一个大集合
     */
    static void flatmap2T(){
        //消费者集合
        List<Consumer> conList = new ArrayList<Consumer>(){
            {
                add(new Consumer("1","jerry","广东深圳"));
                add(new Consumer("2","tom","浙江杭州"));
                add(new Consumer("3","jack","四川成都"));
            }
        };

        //商品集合
        List<Product> proList = new ArrayList<Product>(){
            {
                add(new Product("1","k1","华为","5000"));
                add(new Product("2","k2","小米","4500"));
                add(new Product("3","k3","苹果","6300"));
            }
        };

        conList.stream().flatMap(x->proList.stream().filter(y->x.getUserid().equals(y.getUserid()))
        .map(y->{
            return new HashMap<String,Object>(){
                {
                    put("userid",x.getUsername());
                    put("username",x.getUsername());
                    put("address",x.getAddress());
                    put("prodid",y.getProdid());
                    put("prodname",y.getProdname());
                    put("money",y.getMoney());
                }
            };
        })).collect(Collectors.toList()).forEach(System.out::println);

    }
原文地址:https://www.cnblogs.com/jiyukai/p/14782213.html