代码简洁之道—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); }