整理一下网上 使用java8的stream的一些使用经验。扩展一下自己使用的范围。哈哈
实际例子,
- 抽取List 中的id得到List
List<Long> llist= list.stream().map(item->item.getId()).distinct().collect(Collectors.toList());
或者
List<Long> llist= list.stream().mapToLong(item->item.getId()).boxed().distinct().collect(Collectors.toList());
- 找出最长一行的长度
BufferedReader br = new BufferedReader(new FileReader("c:\\SUService.log"));
int longest = br.lines().
mapToInt(String::length).
max().
getAsInt();
br.close();
System.out.println(longest);
介绍
Stream(流)是一个来自数据源的元素队列并支持聚合操作
流生成方法
- stream() − 为集合创建串行流。
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
- parallelStream() − 为集合创建并行流。
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
int count = strings.parallelStream().filter(string -> string.isEmpty()).count();
- 根据数组构造流
// 1. Individual values
Stream stream = Stream.of("a", "b", "c");
// 2. Arrays
String [] strArray = new String[] {"a", "b", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
流操作类型
- Intermediate:一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。
- Terminal:一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作
数据结构修改的流方法
- map
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
转化大小写
List<String> output = wordList.stream().
map(String::toUpperCase).
collect(Collectors.toList());
- mapToxxx
List<Long> llist= list.stream().mapToLong(item->item.getId()).boxed().distinct().collect(Collectors.toList());
过滤filter,限制输出数量limit,排序sorted,去重distinct,跳过前n个元素skip
skip操作与limit操作相反,如同其字面意思一样,是跳过前n个元素,
- flatMap
flatMap与map的区别在于 flatMap是将一个流中的每个值都转成一个个流,然后再将这些流扁平化成为一个流.参考
- flatMap
终端操作
findFirst
findFirst用于返回满足条件的第一个元素,比如我们希望选出专业为土木工程的排在第一个学生,那么可以实现如下:
Optional<Student> optStu = students.stream().filter(student -> "土木工程".equals(student.getMajor())).findFirst();
findFirst不携带参数,具体的查找条件可以通过filter设置,此外我们可以发现findFirst返回的是一个Optional类型,关于该类型的具体讲解可以参考上一篇:Java8新特性 – Optional类。
findAny
findAny相对于findFirst的区别在于,findAny不一定返回第一个,而是返回任意一个,比如我们希望返回任意一个专业为土木工程的学生,可以实现如下:
Optional<Student> optStu = students.stream().filter(student -> "土木工程".equals(student.getMajor())).findAny();
匹配match
match(Terminal操作) Stream 有三个 match 方法,从语义上说:
- allMatch:Stream 中全部元素符合传入的 predicate,返回 true
- anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true
- noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true
List<Person> persons = new ArrayList();
persons.add(new Person(1, "name" + 1, 10));
persons.add(new Person(2, "name" + 2, 21));
persons.add(new Person(3, "name" + 3, 34));
persons.add(new Person(4, "name" + 4, 6));
persons.add(new Person(5, "name" + 5, 55));
boolean isAllAdult = persons.stream().
allMatch(p -> p.getAge() > 18);
System.out.println("All are adult? " + isAllAdult);
boolean isThereAnyChild = persons.stream().
anyMatch(p -> p.getAge() < 12);
System.out.println("Any child? " + isThereAnyChild);
收集操作collect
规约操作Collectors-
- Collectors将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);
- toArray(new Integer::new)
Integer[] sixNums = {1, 2, 3, 4, 5, 6};
Integer[] evens =
Stream.of(sixNums).filter(n -> n%2 == 0).toArray(Integer[]::new);
3 高级操作-分组。
groupingBy-按照年龄分组
Map<Integer, List<Person>> personGroups = Stream.generate(new PersonSupplier()).
limit(100).
collect(Collectors.groupingBy(Person::getAge));
partitioningBy-按照未成年人和成年人归组
Map<Boolean, List<Person>> children = Stream.generate(new PersonSupplier()).
limit(100).
collect(Collectors.partitioningBy(p -> p.getAge() < 18));
- 转化成值
使用collect可以将Stream转换成值。maxBy和minBy允许用户按照某个特定的顺序生成一个值。
- averagingDouble:求平均值,Stream的元素类型为double
- averagingInt:求平均值,Stream的元素类型为int
- averagingLong:求平均值,Stream的元素类型为long
- counting:Stream的元素个数
- maxBy:在指定条件下的,Stream的最大元素
Optional<Integer> collectMaxBy = Stream.of(1, 2, 3, 4)
.collect(Collectors.maxBy(Comparator.comparingInt(o -> o)));
System.out.println("collectMaxBy:" + collectMaxBy.get());
// 打印结果
// collectMaxBy:4
- minBy:在指定条件下的,Stream的最小元素
- reducing: reduce操作
- summarizingDouble:统计Stream的数据(double)状态,其中包括count,min,max,sum和平均。
- summarizingInt:统计Stream的数据(int)状态,其中包括count,min,max,sum和平均。
- summarizingLong:统计Stream的数据(long)状态,其中包括count,min,max,sum和平均。
- summingDouble:求和,Stream的元素类型为double
- summingInt:求和,Stream的元素类型为int
- summingLong:求和,Stream的元素类型为long
统计
主要产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = integers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());