来源:
我们可以把流想象成一条流水线,流水线的源头是我们的数据源(一个集合),数据源中的元素依次被输送到流水线上,我们可以在流水线上对元素进行各种操作。一旦元素走到了流水线的另一头,那么这些元素就被“消费掉了”,我们无法再对这个流进行操作。当然,我们可以从数据源那里再获得一个新的流重新遍历一遍。
若要对集合进行处理,则需我们手写处理代码,这就叫做外部迭代。而要对流进行处理,我们只需告诉流我们需要什么结果,处理过程由流自行完成,这就称为内部迭代。
list.stream();
Arrays.stream(names);
Stream<String> stream = Stream.of("chaimm","peter","john");
try(Stream lines = Files.lines(Paths.get(“文件路径名”),Charset.defaultCharset())){
//可对lines做一些操作
}catch(IOException e){
}
//PS:Java7简化了IO操作,把打开IO操作放在try后的括号中即可省略关闭IO的代码。
List<Person> result = list.stream()
.filter(Person::isStudent) //使用双冒号,调用这个对象的isStudent参数
// .filter(student -> "武汉大学".equals(student.getSchool()))
.collect(toList());//符合条件的对象组成list
List<Person> result = list.stream()
.distinct() //去重
.collect(toList());
List<Person> result = list.stream()
.limit(3)
.collect(toList());
List<Person> result = list.stream()
.skip(3)
.collect(toList());
List<Student> sortedCivilStudents = students.stream()
.filter(student -> "土木工程".equals(student.getMajor())) //筛选
.sorted((s1, s2) -> s1.getAge() - s2.getAge()) //排序(从小到大)
.limit(2) //前俩个
.collect(Collectors.toList());//组成list
方法2:
public Comparator<DeptLevelDto> deptSeqComparator = Comparator.comparingInt(SysDept::getSeq);
rootList.sort(deptSeqComparator);
方法3:
list.sort((o1,o2)->{return xxx;})
List<String> result = list.stream()
.map(Person::getName)
.collect(toList());
list.stream() //首先将list变成流:
.map(line->line.split(" ")) //按空格分词[00,00],[1111],[222,2],[3333],[4444],会成为5个list
.flagmap(Arrays::stream) //将小流合并成一个大流:5个list整合为1个list
.distinct() //* 去重
.collect(toList());
原数据:[00 00, 1111, 222 2, 3333, 4444]
新数据:[00, 1111, 222, 2, 3333, 4444]
boolean result = list.stream()
.anyMatch(Person::isStudent);
boolean result = list.stream()
.allMatch(Person::isStudent);
boolean result = list.stream() .noneMatch(Person::isStudent);
Optional<Person> person = list.stream().findAny();
Optional--java8新类 为知:Optional-java8.md
Optional<Person> person = list.stream()
.findFirst();
//可以.orElse(T)来返回第一个;中间的其他条件也可以使用;
int age = list.stream().reduce(0, (person1,person2)->person1.getAge()+person2.getAge());
//reduce的第一个参数表示初试值为0;
//reduce的第二个参数为需要进行的归约操作,它接收一个拥有两个参数的Lambda表达式,reduce会把流中的元素两两输给Lambda表达式,最后将计算出累加之和。
Integer提供了sum函数
int age = list.stream().reduce(0, Integer::sum);
//Integer类还提供了min、max等一系列数值操作,当流中元素为数值类型时可以直接使用。
采用reduce进行数值操作会涉及到基本数值类型和引用数值类型之间的装箱、拆箱操作,因此效率较低。
当流操作为纯数值操作时,使用数值流能获得较高的效率。(效率高)
StreamAPI提供了三种数值流:IntStream
、DoubleStream
、LongStream
,也提供了将普通流转换成数值流的三种方法:mapToInt
、mapToDouble
、mapToLong
。
IntStream stream = list.stream()
.mapToInt(Person::getAge);
每种数值流都提供了数值计算函数,如max、min、sum等。
OptionalInt maxAge = list.stream()
.mapToInt(Person::getAge)
.max();
students.stream()
方法1: .mapToInt(Student::getAge).sum();
方法2: .map(Student::getAge).reduce(0, (a, b) -> a + b);
方法3: .map(Student::getAge) .reduce(0, Integer::sum);
方法4: .map(Student::getAge) .reduce(Integer::sum);
由于数值流可能为空,并且给空的数值流计算最大值是没有意义的,因此max函数返回OptionalInt
,它是Optional的一个子类,能够判断流是否为空,并对流为空的情况作相应的处理(.orElse(-1)--注意,返回的是int,不会有Integer)。
此外,mapToInt、mapToDouble、mapToLong进行数值操作后的返回结果分别为:OptionalInt、OptionalDouble、OptionalLong
对处理结果的封装,例如collect(Collectors.toList())
Collectors.reducing()
实现。1.求学生的总人数(size)
方法1:
long count = students.stream().collect(Collectors.counting());
方法2:
long count = students.stream().count();
求最大年龄
方法1:
Optional<Student> olderStudent = students.stream().collect(Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge()));
方法2:
Optional<Student> olderStudent2 = students.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge)));// 进一步简化
求最小年龄
Optional<Student> olderStudent3 = students.stream().collect(Collectors.minBy(Comparator.comparing(Student::getAge)));
summingInt
、summingLong
、summingDouble
averagingInt
。求年龄总和
int totalAge4 = students.stream().collect(Collectors.summingInt(Student::getAge));
一次性得到元素个数、总和、均值、最大值、最小值:
summarizingInt
summarizingLong
summarizingDouble
IntSummaryStatistics statistics = students.stream().collect(Collectors.summarizingInt(Student::getAge));
//IntSummaryStatistics{count=10, sum=220, min=20, average=22.000000, max=24}
String names = students.stream().map(Student::getName).collect(Collectors.joining());
// 输出:孔明伯约玄德云长翼德元直奉孝仲谋鲁肃丁奉
String names = students.stream().map(Student::getName).collect(Collectors.joining(","));
// 输出:孔明,伯约,玄德,云长,翼德,元直,奉孝,仲谋,鲁肃,丁奉
Map<String, List<Student>> groups = students.stream().collect(Collectors.groupingBy(Student::getSchool));
Map<String, Map<String, List<Student>>> groups2 = students.stream().collect(
Collectors.groupingBy(Student::getSchool, // 一级分组,按学校
Collectors.groupingBy(Student::getMajor))); // 二级分组,按专业
Map<String, Long> groups = students.stream().collect(Collectors.groupingBy(Student::getSchool, Collectors.counting()));
如果我们不添加第二个参数,则编译器会默认帮我们添加一个Collectors.toList()。
Map<Boolean, List<Student>> partition = students.stream().collect(Collectors.partitioningBy(student -> "武汉大学".equals(student.getSchool())));
在list使用parallelStream的时候,经常会出现异常,经过测试发现是list的原因,ArrayList是不安全的,若是使用并行处理需要对list进行处理
list=Collections.synchronizedList(list);
list.parallelStream().... 就不会异常了;
原文:https://www.cnblogs.com/ziyue7575/p/6686f5a9711a349e75167adca0651a8b.html