首先创建一个实体类,以及初始化数据
public class Student {
private String name;
private int age;
private int score;
private String email;
private String password;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
}
List<Student> studentList = new ArrayList<>(Arrays.asList(
new Student("小白", 20, 1),
new Student("小黑", 21, 2),
new Student("小红", 22, 3),
new Student("小明", 22, 4),
new Student("小刚", 22, 5)));
List<Student> filter = studentList.stream().filter(x -> x.getAge() > 21).collect(toList());
//去除流中重复元素 (根据流中元素的 hashCode() 和 equals() 方法来实现)
List<Integer> distinct = studentList.stream().map(Student::getAge).distinct().collect(toList());
List<Student> limit = studentList.stream().limit(2).collect(toList());
List<Student> skip = studentList.stream().skip(2).collect(toList());
skip方法与limit方法配合使用可以实现分页的效果
int pageSize = 2; //每页几条
int pageNum = 2; //第几页
List<Student> limitAndSkip = studentList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(toList());
类似的具体到类型 mapToDouble()、mapToInt()、mapToLong()
List<String> map = studentList.stream().map(Student::getName).collect(toList());
类似的还有flatMapToDouble、flatMapToInt、flatMapToLong
//这儿将name拆分成数组转换成流,最后将多个name流合并到一起
List<String> flatMap1 = studentList.stream().flatMap(y -> Arrays.stream(y.getName().split(""))).distinct().collect(toList());
//在定义一个List>
List<Student> studentList1 = new ArrayList<>(Arrays.asList(
new Student("小话", 20, 90),
new Student("小噶", 21, 95),
new Student("小乐", 22, 80),
new Student("小嘻", 22, 82)));
List<List<Student>> lists = new ArrayList<>();
lists.add(studentList);
lists.add(studentList1);
//这儿将lists中的list合并成了一个list
List<Student> flatMap2 = lists.stream().flatMap(Collection::stream).collect(toList());
// 是否有年龄等于44的数据
boolean anyMatch = studentList.stream().anyMatch(x -> x.getAge() == 44);
// 检查谓词是否不匹配流中所有元素
boolean noneMatch = studentList.stream().noneMatch(x -> x.getAge() == 44);
// 检验流中所有元素是否都为true
boolean allMatch = studentList.stream().allMatch(x -> x.getAge() == 44);
有三个参数:
1、U identity
初始值
2、BiFunction accumulator
该函数传入两个参数,返回一个参数,累加器
3、BinaryOperator combiner
组合器,将多个流,应用该函数合并到一起,只有在并行流中生效
//reduce() 一个参数:归约累加 计算所有学生的总成绩
Integer reduce1 = studentList.stream().map(Student::getScore).reduce(Integer::sum).orElse(1);
//reduce 两个参数:设置初始值 然后再相乘
//1*2*3*4*5*10
Integer reduce2 = studentList.stream().map(Student::getScore).reduce(10, (x, y) -> x * y);
//10+1+2+3+4+5
//reduce 两个参数:这儿不是并行流,组合器是无效的,其实就是求和
Integer reduce3 = studentList.stream().map(Student::getScore).reduce(10, Integer::sum, Integer::sum);
//10+1+2+3+4+5 第三个参数,在没有并行流的情况下是无效的,所以结果同上,组合器是相乘但是无效
Integer reduce4 = studentList.stream().map(Student::getScore).reduce(10, Integer::sum, (x, y) -> x * y);
下面介绍在 并行流 中, 组合器 的使用
//并行流reduce,初始值应用在了每个流上然后使用累加器,最后将流合并到一起
// 10+1 10+2 10+3 10+4 10+5 最后将他们全部累加
Integer reduce5 = studentList.stream().map(Student::getScore).parallel().reduce(10, Integer::sum, Integer::sum);
//10*1+10*2+10*3+10*4+10*5
Integer reduce6 = studentList.stream().map(Student::getScore).parallel().reduce(10, (x, y) -> x * y, Integer::sum);
//(10+1)*(10+2)*(10+3)*(10+4)*(10+5)
Integer reduce7 = studentList.stream().map(Student::getScore).parallel().reduce(10, Integer::sum, (x, y) -> x * y);
Student findAny = studentList.stream().findAny().orElse(null);
//forEach() 循环
studentList.stream().forEach(x -> x.setAge(20));
//forEach() 按顺序循环
studentList.stream().forEachOrdered(x -> x.setAge(23));
long count = studentList.stream().count();
Student max = studentList.stream().max(Comparator.comparing(Student::getAge)).orElse(null);
无参或有一个参数
1、Comparator super T> comparator
是一个比较器,传入两个参数,返回一个int,形如(x,y)->{}
这儿有两个比较重要的点:
1、返回一个int类型,返回正数或零x与y位置不变,返回负数交换x与y的位置
2、x是流中后面的元素,y是流中前面的元素
//无参,默认按照升序
List<Integer> sorted1 = studentList.stream().map(Student::getScore).sorted().collect(toList());
//传入一个比较器
List<Student> sorted2 = studentList.stream().sorted(Comparator.comparing(Student::getAge)).collect(toList());
//参照上面的知识点y在前面,x在后面,y比x小则交换位置,所以得出结论
//这儿按照年龄倒序
List<Student> sorted3 = studentList.stream().sorted((x, y) -> {
int xAge = x.getAge();
int yAge = y.getAge();
return yAge - xAge;
}).collect(toList());
//这儿将年龄全都改成23岁
List<Student> peek = studentList.stream().peek(x -> {
x.setAge(23);
}).collect(toList());
有三个参数:
1、Supplier supplier
供给函数,声明具体的容器
2、BiConsumer
累加器,所有的元素执行该函数
3、BiConsumer
组合器,将多个流,应用该函数合并到一起,只有在并行流中生效
List<Integer> intList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
LinkedList<Object> collectList = intList.parallelStream()
.collect(LinkedList::new, (list, i) -> {
System.out.println("【" + i + "】 + 【2】 = 【" + (i + 2) + "】");
list.add(i + 2);
}, (list1, list2) -> {
List<Object> cache = new ArrayList<>(list1);
list1.addAll(list2);
System.out.println("【" + cache + "】.addAll【" + list2 + "】 = 【"+list1+"】");
});
// 【3】 + 【2】 = 【5】
// 【1】 + 【2】 = 【3】
// 【5】 + 【2】 = 【7】
// 【2】 + 【2】 = 【4】
// 【4】 + 【2】 = 【6】
// 【[3]】.addAll【[4]】 = 【[3, 4]】
// 【[6]】.addAll【[7]】 = 【[6, 7]】
// 【[5]】.addAll【[6, 7]】 = 【[5, 6, 7]】
// 【[3, 4]】.addAll【[5, 6, 7]】 = 【[3, 4, 5, 6, 7]】
System.out.println(collectList); // [3, 4, 5, 6, 7]
System.out.println(studentList.stream().parallel().isParallel()); // true
public class StreamTest {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>(Arrays.asList(
new Student("小白", 20, 1),
new Student("小黑", 21, 2),
new Student("小红", 23, 3),
new Student("小明", 24, 4),
new Student("小刚", 25, 5)));
//filter() 过滤获取年龄大于21的学生
//接收一个谓词 (一个返回 boolean 的函数) 作为参数,返回一个包括所有符合谓词的元素流
List<Student> filter = studentList.stream().filter(x -> x.getAge() > 21).collect(toList());
//distinct 去重 年龄去重
//去除流中重复元素 (根据流中元素的 hashCode() 和 equals() 方法来实现)
List<Integer> distinct = studentList.stream().map(Student::getAge).distinct().collect(toList());
//limit 获取前一个数据
//截断流,返回一个不超过指定长度的流
List<Student> limit = studentList.stream().limit(1).collect(toList());
//skip() 跳过前几个数据
//跳过元素,返回一个跳过了前 n 个元素的流
List<Student> skip = studentList.stream().skip(2).collect(toList());
// limit 配合skip可以有高级用法,比如查询分页
int pageSize = 2; //每页几条
int pageNum = 2; //第几页
List<Student> limitAndSkip = studentList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(toList());
//map() 接收一个函数作为参数,将该函数应用到流中每个元素上,并将其映射成一个新的元素,返回由新元素组成的流
//将studentList获取name流并转换成集合 类似的 mapToDouble()、mapToInt()、mapToLong()
List<String> map = studentList.stream().map(Student::getName).collect(toList());
List<Student> studentList1 = new ArrayList<>(Arrays.asList(
new Student("小话", 20, 90),
new Student("小噶", 30, 95),
new Student("小乐", 40, 80),
new Student("小嘻", 50, 82)));
List<List<Student>> lists = new ArrayList<>();
lists.add(studentList);
lists.add(studentList1);
//flatMap 扁平化也可以理解为合并流,这儿就是将Name分段成数组,转换成流合并到一起去重并返回
//类似的根据类型flatMapToDouble、flatMapToInt、flatMapToLong
List<String> flatMap1 = studentList.stream().flatMap(y -> Arrays.stream(y.getName().split(""))).distinct().collect(toList());
//可以将list内的list合并成一个list如下
List<Student> flatMap2 = lists.stream().flatMap(Collection::stream).collect(toList());
//anyMatch() 检查谓词是否至少匹配流中一个元素
boolean anyMatch = studentList.stream().anyMatch(x -> x.getAge() == 44);
//noneMatch() 检查谓词是否不匹配流中所有元素
boolean noneMatch = studentList.stream().noneMatch(x -> x.getAge() == 44);
boolean allMatch = studentList.stream().allMatch(x -> x.getAge() == 44);
//reduce() 归约累加 计算所有学生的总成绩
Integer reduce1 = studentList.stream().map(Student::getScore).reduce(Integer::sum).orElse(1);
//reduce 设置初始值 然后再相加
//1*2*3*4*5*10
Integer reduce2 = studentList.stream().map(Student::getScore).reduce(10, (x, y) -> x * y);
//10+1+2+3+4+5
Integer reduce3 = studentList.stream().map(Student::getScore).reduce(10, Integer::sum, Integer::sum);
//10+1+2+3+4+5 第三个参数,在没有并行流的情况下是无效的,所以结果同上
Integer reduce4 = studentList.stream().map(Student::getScore).reduce(10, Integer::sum, (x, y) -> x * y);
//10*1+2+3+4+5
// 10+1 10+2 10+3 10+4 10+5 运行流程并行流,第三个参数可省略,默认使用第二个参数合并流
Integer reduce5 = studentList.stream().map(Student::getScore).parallel().reduce(10, Integer::sum, Integer::sum);
//10*1+10*2+10*3+10*4+10*5
Integer reduce6 = studentList.stream().map(Student::getScore).parallel().reduce(10, (x, y) -> x * y, Integer::sum);
//(10+1)*(10+2)*(10+3)*(10+4)*(10+5)
Integer reduce7 = studentList.stream().map(Student::getScore).parallel().reduce(10, Integer::sum, (x, y) -> x * y);
//findFirst()返回第一个
//findAny()返回随机一个
Student findAny = studentList.stream().findAny().orElse(null);
//forEach() 循环
// studentList.stream().forEach(x -> x.setAge(20));
//forEach() 按顺序循环
// studentList.stream().forEachOrdered(x -> x.setAge(23));
//count() 获得流中的个数
long count = studentList.stream().count();
//max()、 min()
Student max = studentList.stream().max(Comparator.comparing(Student::getAge)).orElse(null);
//sorted() 排序
List<Integer> sorted1 = studentList.stream().map(Student::getScore).sorted().collect(toList());
List<Student> sorted2 = studentList.stream().sorted(Comparator.comparing(Student::getAge)).collect(toList());
List<Student> sorted3 = studentList.stream().sorted((x, y) -> {
int xAge = x.getAge();
int yAge = y.getAge();
return yAge - xAge;
}).collect(toList());
//peek() 接收一个 Consumer 函数作为参数,并将该函数应用到流中每个元素上
List<Student> peek = studentList.stream().peek(x -> {
x.setAge(23);
}).collect(toList());
//collect()
LinkedList<Object> collect = studentList.stream().parallel().collect(LinkedList::new, LinkedList::add, LinkedList::addAll);
//parallel():并行流
//isParallel():是否是并行流
List<Student> parallel = studentList.stream().parallel().collect(toList());
//close关闭流
//onClose关闭流时调用该方法
Stream<Student> onClose = studentList.stream().onClose(() -> System.out.println("哈哈哈哈哈哈哈"));
onClose.close();
//iterator() 流的迭代器
Iterator<Student> iterator = studentList.stream().iterator();
//sequential() 返回顺序的等效流
//unordered() 与之相反的,无序的
studentList.stream().sequential();
//spliterator()
Spliterator<Student> spliterator = studentList.stream().spliterator();
spliterator.forEachRemaining(System.out::println);
//Stream.of()
//Stream.empty()
//Stream.concat()
//Stream.builder()
//Stream.iterate()
//Stream.generate()
List<Integer> intList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
LinkedList<Object> collectList = intList.parallelStream()
.collect(LinkedList::new, (list, i) -> {
System.out.println("【" + i + "】 + 【2】 = 【" + (i + 2) + "】");
list.add(i + 2);
}, (list1, list2) -> {
List<Object> cache = new ArrayList<>(list1);
list1.addAll(list2);
System.out.println("【" + cache + "】.addAll【" + list2 + "】 = 【" + list1 + "】");
});
}
}