java流式编程_【java】集合流式编程总结

在具体的介绍之前,先总结一波常用的写法,有基础的可以直接拿来用,没有基础的可以先跳过,看完下面的基础再回来看

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

List userList = new ArrayList<>();

userList.addAll(Arrays.asList(new User(1, 11, "张三"),new User(1, 11, "张三"),new User(2, 22, "李四"),new User(1, 33, "王五"),new User(2, 44, "赵六"),new User(2, 44, "赵六")));//----------------------------------------------中间操作----------------------------------------------//【filter】从列表中筛选出性别为女的数据

List filterUsage = userList.stream().filter(s->s.getSex() == 2).collect(Collectors.toList());//结果:[User(sex=2, age=22, name=李四), User(sex=2, age=44, name=赵六), User(sex=2, age=44, name=赵六)]

System.out.println(filterUsage);//【distinct】从列表中去重

List distinctUsage =userList.stream().distinct().collect(Collectors.toList());//结果:[User(sex=1, age=11, name=张三), User(sex=2, age=22, name=李四), User(sex=1, age=33, name=王五), User(sex=2, age=44, name=赵六)]

System.out.println(distinctUsage);//【sorted】按照年龄字段从大到小重新排序 (从小到大就是s1.getAge()-s2.getAge())

List sortedUsage = userList.stream().sorted((s1,s2)->s2.getAge()-s1.getAge()).collect(Collectors.toList());//结果:[User(sex=2, age=44, name=赵六), User(sex=2, age=44, name=赵六), User(sex=1, age=33, name=王五), User(sex=2, age=22, name=李四), User(sex=1, age=11, name=张三), User(sex=1, age=11, name=张三)]

System.out.println(sortedUsage);//【limit】获取前两条数据

List limitUsage = userList.stream().limit(2).collect(Collectors.toList());//结果:[User(sex=1, age=11, name=张三), User(sex=1, age=11, name=张三)]

System.out.println(limitUsage);//【skip】跳过前两条,之后获取前三条数据

List skipUsage = userList.stream().skip(2).limit(3).collect(Collectors.toList());//结果:[User(sex=2, age=22, name=李四), User(sex=1, age=33, name=王五), User(sex=2, age=44, name=赵六)]

System.out.println(skipUsage);//【map】获取所有人的姓名

List mapUsage =userList.stream().map(User::getName).collect(Collectors.toList());//结果:[张三, 张三, 李四, 王五, 赵六, 赵六]

System.out.println(mapUsage);//【flatMap】//【Collectors工具类一些常用方法】//【groupingBy】分组//将集合中的数据按照姓名分组

Map> groupingByUsage = userList.stream().collect(Collectors.groupingBy(s ->s.getName()));//结果:{李四=[User(sex=2, age=22, name=李四)], 张三=[User(sex=1, age=11, name=张三), User(sex=1, age=11, name=张三)],//王五=[User(sex=1, age=33, name=王五)], 赵六=[User(sex=2, age=44, name=赵六), User(sex=2, age=44, name=赵六)]}

System.out.println(groupingByUsage);//将集合中的数据按照姓名+性别分组

Map> groupingByUsage2 = userList.stream().collect(Collectors.groupingBy(s -> s.getName() + "#" +s.getSex()));//结果:{张三#1=[User(sex=1, age=11, name=张三), User(sex=1, age=11, name=张三)], 李四#2=[User(sex=2, age=22, name=李四)],//赵六#2=[User(sex=2, age=44, name=赵六), User(sex=2, age=44, name=赵六)], 王五#1=[User(sex=1, age=33, name=王五)]}

System.out.println(groupingByUsage2);//【maxBy】获取集合中年龄最大的对象信息

User maxByUsage = userList.stream().collect(Collectors.maxBy((s1, s2) -> s1.getAge() -s2.getAge())).get();//结果:User(sex=2, age=44, name=赵六)

System.out.println(maxByUsage);//【minBy】获取集合中年龄最小的对象信息

User minByUsage = userList.stream().collect(Collectors.minBy((s1, s2) -> s1.getAge() -s2.getAge())).get();//结果:User(sex=1, age=11, name=张三)

System.out.println(minByUsage);//【joining】拼接集合中所有的用户名称---直接拼接

String joiningUsage =userList.stream().map(User::getName).collect(Collectors.joining());//结果:张三张三李四王五赵六赵六

System.out.println(joiningUsage);//拼接中间加上逗号

String joiningUsage2 = userList.stream().map(User::getName).collect(Collectors.joining(","));//结果:张三,张三,李四,王五,赵六,赵六

System.out.println(joiningUsage2);//拼接中间加上逗号,两边加上前后缀

String joiningUsage3 = userList.stream().map(User::getName).collect(Collectors.joining(",","[","]"));//结果:[张三,张三,李四,王五,赵六,赵六]

System.out.println(joiningUsage3);//【counting】获取集合中对象的数量

Long countingUsage =userList.stream().collect(Collectors.counting());//结果:6

System.out.println(countingUsage);//【summingInt】获取集合中所有对象年龄的和

int summingIntUsage =userList.stream().collect(Collectors.summingInt(User::getAge));//结果:165

System.out.println(summingIntUsage);//【averagingInt】获取集合中所有对象年龄的平均值

Double averagingIntUsage =userList.stream().collect(Collectors.averagingInt(User::getAge));//结果:27.5

System.out.println(averagingIntUsage);//【summarizingInt】获取集合中所有对象的数量/和/最大值/最小值/平均值等信息

IntSummaryStatistics summarizingIntUsage =userList.stream().collect(Collectors.summarizingInt(User::getAge));//结果:IntSummaryStatistics{count=6, sum=165, min=11, average=27.500000, max=44}

System.out.println(summarizingIntUsage);//----------------------------------------------最终操作----------------------------------------------//【collect】//这里不做演示,上面的所有例子中都有用到//【reduce】将集合中的所有性别字段的值按照相加的规则求乘积

Integer reduceUsage = userList.stream().map(User::getSex).reduce((s1, s2) -> s1 *s2).get();//结果:8

System.out.println(reduceUsage);//【count】求集合中对象的数量

long countUsage =userList.stream().count();//结果:6

System.out.println(countUsage);//【forEach】遍历出所有的对象的名称

Consumer action =System.out::println;//结果:张三 张三 李四 王五 赵六 赵六

userList.stream().map(User::getName).forEach(action);//【max&min】获取集合中所有对象中年龄的最大值和最小值

Integer maxUsage =userList.stream().map(User::getAge).max(Integer::compareTo).get();//结果:44

System.out.println(maxUsage);

Integer minUsage=userList.stream().map(User::getAge).min(Integer::compareTo).get();//结果:11

System.out.println(minUsage);//【Matching -> allMatch、anyMatch、noneMatch】//allMatch:只有当流中所有的元素,都匹配指定的规则,才会返回true

boolean allMatchUsage = userList.stream().map(User::getAge).allMatch(e -> e >= 44);//结果:false

System.out.println(allMatchUsage);//anyMatch:只要流中有任意的数据,满足指定的规则,都会返回true

boolean anyMatchUsage = userList.stream().map(User::getAge).anyMatch(e -> e <= 11);//结果:true

System.out.println(anyMatchUsage);//noneMatch:只有当流中所有的元素,都不满足指定的规则,才会返回true

boolean noneMatchUsage = userList.stream().map(User::getAge).noneMatch(e -> e < 11);//结果:true

System.out.println(noneMatchUsage);//【find--> findFirst、findAny】【parallelStream并行流、stream串行流】//findFirst:从流中获取开头第一个元素

User user =userList.stream().findFirst().get();//结果:User(sex=1, age=11, name=张三)

System.out.println(user);

User user2=userList.parallelStream().findFirst().get();//结果:User(sex=1, age=11, name=张三)

System.out.println(user2);//findAny:单线程是获取第一个元素,多线程可能不一样

User user3 =userList.stream().findAny().get();//结果:User(sex=1, age=11, name=张三)

System.out.println(user3);

User user4=userList.parallelStream().findAny().get();//结果:User(sex=1, age=33, name=王五)

System.out.println(user4);//【IntStream+summaryStatistics】获取int数组中的最大值//1.准备一个int数组作为数据源

int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};//2.读取数据到流中,获取IntStream对象

IntStream intStream =Arrays.stream(array);//两种方法:(不能一起用,因为是中间操作)//1. 直接通过IntStream来获取//System.out.println(intStream.max().getAsInt());//2. 通过IntSummaryStatistics,里面包括最大/最小/平均/数量等方法

IntSummaryStatistics intSummaryStatistics =intStream.summaryStatistics();//结果:9

System.out.println(intSummaryStatistics.getMax());//----------------------------------------------其它操作----------------------------------------------//【list转数组1】

Integer[] ints = userList.stream().map(User::getAge).toArray(Integer[]::new);//【list转数组2】

List list = newArrayList();

list.add("1");

list.add("2");

list.add("3");

String[] strings= list.toArray(newString[list.size()]);//【数组转list】

String[] arrays = {"1", "2", "3"};

List listStrings =Stream.of(arrays).collect(Collectors.toList());//结果:[1, 2, 3]

System.out.println(listStrings);//【修改集合中的对象属性的值】//原值:[User(sex=1, age=11, name=张三), User(sex=1, age=11, name=张三), User(sex=2, age=22, name=李四),//User(sex=1, age=33, name=王五), User(sex=2, age=44, name=赵六), User(sex=2, age=44, name=赵六)]

System.out.println(userList);

userList.forEach(s->{

s.setAge(100);

s.setSex(100);

});//新值:[User(sex=100, age=100, name=张三), User(sex=100, age=100, name=张三),User(sex=100, age=100, name=李四),//User(sex=100, age=100, name=王五), User(sex=100, age=100, name=赵六), User(sex=100, age=100, name=赵六)]

System.out.println(userList);

View Code

一、集合流的简介

1. 集合的流式编程的简介

Stream是JDK1.8之后出现的新特性,也是JDK1.8新特性中最值得学习的两种新特性之一(另一个是lambda表达式)Stream是对集合操作的增强,流不是集合的元素,不是一种数据结构,不负责数据的存储的。流更像是一个迭代器,可以单向的遍历一个集合中的每一个元素,并且不可循环。

2. 为什么要使用集合的流式编程

有些时候,对集合中的元素进行操作的时候,需要使用到其他操作的结果。在这个过程中,集合的流式编程可以大幅度的简化代码的数量。将数据源中的数据,读取到一个流中,可以对这个流中的数据进行操作(删除、过滤、映射...)。每次的操作结果也是一个流对象,可以对这个流再进行其它的操作。

3. 使用流式编程的步骤

通常情况下,对集合中的数据使用流式编程,需要经过以下三步:

(1)获取数据源,将数据源中的数据读取到流中

(2)对流中的数据进行各种各样的处理

(3)对流中的数据进行整合处理

在上述三个过程:

(1)过程2中,有若干方法,可以对流中的数据进行各种各样的操作,并且返回流对象本身,这样的操作,被称为中间操作

(2)过程3中,有若干方法,可以对流中的数据进行各种处理,并关闭流,这样的操作,被称为最终操作

在中间操作和最终操作中,基本上所有的方法参数都是函数式接口,可以使用lambda表达式来实现。使用集合的流式编程,来简化代码量。

二、数据源的获取

1. 数据源的简介

数据源,顾名思义,就是流中的数据的来源,是集合的流式编程的第一步,将数据源中的数据读取到流中,进行处理。注意:将数据读取到流中进行处理的时候,与数据源中的数据没有关系。也就是说,中间操作对流中的数据进行处理、过滤、映射、排序...是不会影响到数据源中的数据的。

2. 数据源的获取

这个过程,其实是将一个容器中的数据,读取到一个流中,因此无论什么容器作为数据源,读取到流中的方法返回值一定是一个Stream。

public static void main(String[] args) throwsException{//将集合作为数据源,读取集合中的数据到一个流中

collectionDataSource();//将数组作为数据源,读取数组中的数据到一个流中(使用引用数据类型)

arrayDataSource();//将数组作为数据源,读取数组中的数据到一个流中(使用基本数据类型)

}//将集合作为数据源,读取集合中的数据到一个流中

public static voidcollectionDataSource(){//1.实例化一个集合

List list = new ArrayList<>();//2.填充元素

Collections.addAll(list,0,1,2,3,4,5,6,7,8,9);//3.读取集合中的数据,将其读取到流中//Stream stream = list.stream();//同步流

Stream integerStream = list.parallelStream();//并发流//4.输出stream

System.out.println(integerStream);//java.util.stream.ReferencePipeline$Head@4554617c

}//将数组作为数据源,读取数组中的数据到一个流中

public static voidarrayDataSource(){//1.实例化一个数组

Integer[] array = new Integer[]{0,1,2,3,4,5,6,7,8,9};//2.读取数组中的数据到流中,得到一个流对象

Stream stream =Arrays.stream(array);//3.输出Stream

System.out.println(stream);

}//将数组作为数据源,读取数组中的数据到一个流中//集合中只能存引用数据类型,但是数组中不用

public static voidarrayDataSource2(){//1.实例化一个数组

int[] array = new int[]{0,1,2,3,4,5,6,7,8,9};//2.读取数组中的数据到流中,得到一个流对象

IntStream stream =Arrays.stream(array);//3.输出Stream

System.out.println(stream);

}

三、最终操作

将流中的数据整合到一起,可以存入一个集合,也可以直接对流中的数据进行遍历,数据统计...通过最终操作,需要掌握如何从流中提取出来我们想要的信息。

注意事项:最终操作,在执行结束之后,会关闭这个流,流中的所有数据都会被销毁,如果使用一个已经关闭了的流,会出现异常。

最终操作包括:collect、reduce、count、forEach、max&min、Matching、find、IntStream等。

1. collect

将流中的数据收集到一起,对这些数据进行一些处理。最常见的处理,就是将流中的数据存入一个集合。collect方法的参数,是一个collector接口,而且这个接口并不是一个函数式接口,实现这个接口,可以自定义收集的规则。但是,绝大部分情况下,不需要自定义。

直接使用Collectors工具类提供的方法即可。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classFinalOperation {public static voidmain(String[] args) {

collectUsage();

}//最终操作:collect将流中的数据整合起来,最常见的处理是:读取流中的数据,整合到一个容器中,得到一个集合。

public static voidcollectUsage(){//1.读取数据源

Stream dataSource =getDataSource();//2.流中的数据的聚合//List list = dataSource.collect(Collectors.toList());//System.out.println(list);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]//Set set = dataSource.collect(Collectors.toSet());//System.out.println(set);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]//Map map = dataSource.collect(Collectors.toMap(i -> i.toString(), i -> i));//i.toString作为键 i作为值

Map map = dataSource.collect(Collectors.toMap(Object::toString, i -> i));//i.toString作为键 i作为值

System.out.println(map);//{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}

}//数据源的获取,从一个容器中获取数据源中的数据(得到一个Stream对象)

public static StreamgetDataSource(){//1.准备一个容器

List dataSource = new ArrayList<>();//2.向数据源中添加数据

Collections.addAll(dataSource, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);//3.读取数据源中的数据,得到Stream对象

returndataSource.stream();

}

}

View Code

2. reduce

将流中的数据按照一定的规则聚合起来。将流的元素,逐一带入这个方法中,进行运算。最终的运算结果,得到的其实是一个Optional类型,需要使用get()获取到里面的数据

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classFinalOperation {public static voidmain(String[] args) {

reduceUsage();

}public static voidreduceUsage(){//1.读取数据源,得到流对象

Stream dataSource =getDataSource();//2.最终操作 (这里有两个参数,实现了从0到9的和的求值 即p1=0 p2=1 和的结果为1作为p1 再跟p2=2相加,以此类推)

Integer num = dataSource.reduce((p1, p2) -> p1 +p2).get();//Integer num = dataSource.reduce(Integer::sum).get();//3.输出

System.out.println(num);//45

}//数据源的获取,从一个容器中获取数据源中的数据(得到一个Stream对象)

public static StreamgetDataSource(){//1.准备一个容器

List dataSource = new ArrayList<>();//2.向数据源中添加数据

Collections.addAll(dataSource, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);//3.读取数据源中的数据,得到Stream对象

returndataSource.stream();

}

}

View Code

3. count

统计流中的元素数量

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classFinalOperation {public static voidmain(String[] args) {

countUsage();

}public static voidcountUsage(){//1.读取数据源,得到流对象

Stream dataSource =getDataSource();//2.最终操作 获取元素数量

Long num =dataSource.count();//3.输出

System.out.println(num);//10

}//数据源的获取,从一个容器中获取数据源中的数据(得到一个Stream对象)

public static StreamgetDataSource(){//1.准备一个容器

List dataSource = new ArrayList<>();//2.向数据源中添加数据

Collections.addAll(dataSource, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);//3.读取数据源中的数据,得到Stream对象

returndataSource.stream();

}

}

View Code

4. forEach

迭代、遍历流中的数据

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classFinalOperation {public static voidmain(String[] args) {

forEachUsage();

}public static voidforEachUsage(){//1.读取数据源,得到流对象

Stream dataSource =getDataSource();//2.最终操作 遍历流中的数据 输出

dataSource.forEach(System.out::print);//0123456789

}//数据源的获取,从一个容器中获取数据源中的数据(得到一个Stream对象)

public static StreamgetDataSource(){//1.准备一个容器

List dataSource = new ArrayList<>();//2.向数据源中添加数据

Collections.addAll(dataSource, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);//3.读取数据源中的数据,得到Stream对象

returndataSource.stream();

}

}

View Code

5. max&min

获取流中的最大/最小元素

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classFinalOperation {public static voidmain(String[] args) {

maxAndMinUsage();

}//按照执行的对象比较的规则去进行大小的比较,然后得出流中最大、最小的数据

public static voidmaxAndMinUsage(){//1.读取数据源,得到流对象

Stream dataSource =getDataSource();//2.最终操作 获取流中的最大、最小值//Integer max = dataSource.max(Integer::compareTo).get();//System.out.println(max);//9

Integer min =dataSource.min(Integer::compareTo).get();

System.out.println(min);//0

}//数据源的获取,从一个容器中获取数据源中的数据(得到一个Stream对象)

public static StreamgetDataSource(){//1.准备一个容器

List dataSource = new ArrayList<>();//2.向数据源中添加数据

Collections.addAll(dataSource, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);//3.读取数据源中的数据,得到Stream对象

returndataSource.stream();

}

}

View Code

6. Matching

allMatch:只有当流中所有的元素,都匹配指定的规则,才会返回true

anyMatch:只要流中有任意的数据,满足指定的规则,都会返回true

noneMatch:只有当流中所有的元素,都不满足指定的规则,才会返回true

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public static voidmain(String[] args) {

matchingUsage();

}public static voidmatchingUsage(){//1.读取数据源,获取Stream对象

Stream dataSource =getDataSource();//2.匹配的操作//boolean b = dataSource.allMatch(e -> e>0);//System.out.println(b);//false 因为不是集合中所有的元素都大于0 还有一个等于0//boolean b = dataSource.anyMatch(e -> e >= 9);//System.out.println(b);//true

boolean b = dataSource.noneMatch(e -> e > 9);

System.out.println(b);//true

}//数据源的获取,从一个容器中获取数据源中的数据(得到一个Stream对象)

public static StreamgetDataSource(){//1.准备一个容器

List dataSource = new ArrayList<>();//2.向数据源中添加数据

Collections.addAll(dataSource, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);//3.读取数据源中的数据,得到Stream对象

returndataSource.stream();

}

View Code

7. find

findFirst:从流中获取一个元素(是获取的开头元素)

findAny:从流中获取一个元素(一般情况下,是获取的开头的元素)

这两个方法,绝大部分情况下,是完全相同的,但是在多线程环境下,返回结果可能不一样

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public static voidmain(String[] args) {

findUsage();

}public static voidfindUsage(){//1.实例化一个集合

ArrayList dataSource = new ArrayList<>();

Collections.addAll(dataSource,0, 1, 2, 3, 4, 5, 6, 7, 8, 9);//2.findFirst演示//Integer integer = dataSource.stream().findFirst().get();//串行流//Integer integer = dataSource.parallelStream().findFirst().get();//并行流//System.out.println(integer);//串行流或者是并行流结果都是0//3.findAny演示//Integer integer = dataSource.stream().findAny().get();//串行流

Integer integer = dataSource.parallelStream().findAny().get();//并行流

System.out.println(integer);//串行流是0、并行流结果为6 即不一定是0

}

View Code

8. IntStream

主要可以实现获取流中int类型数据的最大值、最小值、平均值、和、数量

还可以获取到一个对流中数据的分析结果(即一次获取所有类型的值)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public static voidmain(String[] args) {

intStreamUsage();

}public static voidintStreamUsage(){//1.准备一个int数组作为数据源

int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};//2.读取数据到流中,获取IntStream对象

IntStream stream =Arrays.stream(array);//3.输出//System.out.println(stream.max().getAsInt());//获取最大值 9//System.out.println(stream.min().getAsInt());//获取最小值 0//System.out.println(stream.sum());//获取和 45//System.out.println(stream.count());//获取流中数据个数 10//System.out.println(stream.average().getAsDouble());//获取流中数据的平均值 4.5//4.获取到一个对流中数据的分析结果(即一次获取所有类型的值)

IntSummaryStatistics intSummaryStatistics =stream.summaryStatistics();

System.out.println("最大值:"+intSummaryStatistics.getMax()+" 最小值:"+intSummaryStatistics.getMin());//最大值:9 最小值:0

System.out.println("平均值:"+intSummaryStatistics.getAverage()+" 和:"+intSummaryStatistics.getSum());//平均值:4.5 和:45

System.out.println("数量:"+intSummaryStatistics.getCount());//数量:10

}

View Code

四、中间操作

将数据从数据源中读取到流中,就是对流中的数据进行各种各样的操作、处理。中间操作可以连续操作,每一个操作的返回值都是一个Stream对象,可以继续进行其他的操作,直到最终操作。

中间操作主要分为:filter、distinct、sorted、limit&skip、map&flatMap、Collections工具类

1. filter

条件过滤,仅保留流中满足指定条件的数据,其他不满足的数据都会被删除。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//学生类:存储于集合中的数据类型

private static classStudent{privateString name;private intage;private intscore;public Student(String name, int age, intscore) {this.name =name;this.age =age;this.score =score;

}//这里省略getter、setter、toString方法

}public static voidmain(String[] args) {

filterUsage();

}public static voidfilterUsage(){//1. 获取数据源

Stream dataSource =getDataSource();//2. 过滤掉集合中成绩不合格的学生信息

dataSource.filter(s -> s.getScore()>=60).forEach(System.out::println);//Student{name='xiaoming', age=18, score=100}//Student{name='xiaoming', age=19, score=90}//Student{name='xiaoming', age=20, score=80}//Student{name='xiaoming', age=21, score=70}//Student{name='xiaoming', age=22, score=60}

}//读取数据源,将集合中存储的数据,读取到数据源中

public static StreamgetDataSource(){//1.实例化一个集合,存Student对象

ArrayList arrayList = new ArrayList<>();//2.添加若干数据

Collections.addAll(arrayList,new Student("xiaoming",18,100),new Student("xiaoming",19,90),new Student("xiaoming",20,80),new Student("xiaoming",21,70),new Student("xiaoming",22,60),new Student("xiaoming",23,50),new Student("xiaoming",24,40)

);//3.读取数据源,得到Stream对象

returnarrayList.stream();

}

View Code

2. distinct

去除集合中重复的元素,这个方法没有参数,去重的规则与HashSet相同。

(1)比较两个对象的hashcode

(2)使用equals再来对比一下

这里要注意:实体类中需要重写hashcode和equals方法,否则去重可能不会生效

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//学生类:存储于集合中的数据类型

private static classStudent{privateString name;private intage;private intscore;public Student(String name, int age, intscore) {this.name =name;this.age =age;this.score =score;

}//这里省略getter、setter、toString、hashcode、equals方法

}public static voidmain(String[] args) {

distinctUsage();

}public static voiddistinctUsage(){//1. 获取数据源

Stream dataSource =getDataSource();//2. 去重 要注意实体类Student中需要重写equals和hashCode方法,否则去重不会生效

dataSource.distinct().forEach(System.out::println);//Student{name='xiaoming1', age=18, score=100}//Student{name='xiaoming2', age=20, score=80}//Student{name='xiaoming3', age=21, score=70}//Student{name='xiaoming4', age=22, score=60}//Student{name='xiaoming5', age=23, score=50}//Student{name='xiaoming6', age=24, score=40}

}//读取数据源,将集合中存储的数据,读取到数据源中

public static StreamgetDataSource(){//1.实例化一个集合,存Student对象

ArrayList arrayList = new ArrayList<>();//2.添加若干数据

Collections.addAll(arrayList,new Student("xiaoming1",18,100),new Student("xiaoming1",18,100),new Student("xiaoming2",20,80),new Student("xiaoming3",21,70),new Student("xiaoming4",22,60),new Student("xiaoming5",23,50),new Student("xiaoming6",24,40)

);//3.读取数据源,得到Stream对象

returnarrayList.stream();

}

View Code

3. sorted

对流中的数据进行排序

(1)无参:sorted():将流中的数据,按照其对应的类实现的Comparable接口提供的比较规则进行排序

(2)有参:sorted(Comparator comparator):将流中的数据,按照参数接口提供的比较规则进行排序

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

private static class Student implements Comparable{privateString name;private intage;private intscore;public Student(String name, int age, intscore) {this.name =name;this.age =age;this.score =score;

}

@Overridepublic intcompareTo(Student o) {return score-o.score;

}//这里省略getter、setter、toString、hashcode、equals方法

}public static voidmain(String[] args) {

sortedUsage();

}public static voidsortedUsage(){//1. 获取数据源

Stream dataSource =getDataSource();//2. 将流中的数据进行排序 (注意实体类要注意实现Comparable接口并重写compareTo方法,否则会报错)//dataSource.sorted().forEach(System.out::println);//Student{name='xiaoming6', age=24, score=40}//Student{name='xiaoming5', age=23, score=50}//Student{name='xiaoming4', age=22, score=60}//Student{name='xiaoming3', age=21, score=70}//Student{name='xiaoming2', age=20, score=80}//Student{name='xiaoming1', age=18, score=100}//Student{name='xiaoming1', age=18, score=100}//3. 对流中的数据按照自定义的规则进行排序 (按照年龄升序排列)

dataSource.sorted((s1,s2)->s1.getAge()-s2.getAge()).forEach(System.out::println);//Student{name='xiaoming1', age=18, score=100}//Student{name='xiaoming1', age=18, score=100}//Student{name='xiaoming2', age=20, score=80}//Student{name='xiaoming3', age=21, score=70}//Student{name='xiaoming4', age=22, score=60}//Student{name='xiaoming5', age=23, score=50}//Student{name='xiaoming6', age=24, score=40}

}//读取数据源,将集合中存储的数据,读取到数据源中

public static StreamgetDataSource(){//1.实例化一个集合,存Student对象

ArrayList arrayList = new ArrayList<>();//2.添加若干数据

Collections.addAll(arrayList,new Student("xiaoming1",18,100),new Student("xiaoming1",18,100),new Student("xiaoming2",20,80),new Student("xiaoming3",21,70),new Student("xiaoming4",22,60),new Student("xiaoming5",23,50),new Student("xiaoming6",24,40)

);//3.读取数据源,得到Stream对象

returnarrayList.stream();

}

View Code

4. limit&skip

limit:限制,截取流中指定数量的元素   skip:跳过流中的指定数量的元素 经常放在一起用

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//实体类省略,参考上面即可

public static voidmain(String[] args) {

limitAndSkipUsage();

}public static voidlimitAndSkipUsage(){//1. 获取数据源

Stream dataSource =getDataSource();//2. 获取成绩的前5名//dataSource.distinct()//.sorted((s1,s2)->s2.getScore()-s1.getScore())//.limit(5)//.forEach(System.out::println);//3. 获取成绩为3-5名的

dataSource.distinct()

.sorted((s1,s2)->s2.getScore()-s1.getScore())

.limit(5)

.skip(2)

.forEach(System.out::println);

}//读取数据源,将集合中存储的数据,读取到数据源中

public static StreamgetDataSource(){//1.实例化一个集合,存Student对象

ArrayList arrayList = new ArrayList<>();//2.添加若干数据

Collections.addAll(arrayList,new Student("xiaoming1",18,100),new Student("xiaoming1",18,100),new Student("xiaoming2",20,80),new Student("xiaoming3",21,70),new Student("xiaoming4",22,60),new Student("xiaoming5",23,50),new Student("xiaoming6",24,40)

);//3.读取数据源,得到Stream对象

returnarrayList.stream();

}

View Code

5. map&flatMap

对流中的数据进行映射,用新的数据替换旧的数据

map最主要,就是来做元素的替换,其实map是一个元素的映射(将流中每一个元素替换成指定的元素)

flatMap也是元素的映射,flatMap是扁平化映射

扁平化映射:一般用在map映射完成后,流中的数据是一个容器,而我们需要对容器中的数据进行处理 此时使用扁平化映射,可以将流中的容器中的数据,直接读取到流中

案例1:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public static voidmain(String[] args) {

mapUsage();

}public static voidmapUsage(){//1. 获取数据源

Stream dataSource =getDataSource();//2. 实际需求:获取所有学生的名字//dataSource.map(Student::getName).forEach(System.out::println);//dataSource.map(s->s.getName()).forEach(System.out::println);//3. 实际需求:获取所有学生的成绩 注意:泛型中不能是基本数据类型,只能是包装类 即下面的返回值应该为Stream//dataSource.map(Student::getScore).forEach(System.out::println);//4. 实际需求:获取所有学生的成绩

IntSummaryStatistics intSummaryStatistics =dataSource.mapToInt(Student::getScore).summaryStatistics();

System.out.println(intSummaryStatistics.getMax());

}//读取数据源,将集合中存储的数据,读取到数据源中

public static StreamgetDataSource(){//1.实例化一个集合,存Student对象

ArrayList arrayList = new ArrayList<>();//2.添加若干数据

Collections.addAll(arrayList,new Student("xiaoming1",18,100),new Student("xiaoming1",18,100),new Student("xiaoming2",20,80),new Student("xiaoming3",21,70),new Student("xiaoming4",22,60),new Student("xiaoming5",23,50),new Student("xiaoming6",24,40)

);//3.读取数据源,得到Stream对象

returnarrayList.stream();

}

View Code

案例2:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public static voidmain(String[] args) {

mapUsage();

}public static voidmapUsage(){//1.实例化一个字符串数组

String[] array = {"hello","world"};//2.将字符串数组中的数据读取到流中

Stream stream =Arrays.stream(array);//3.需求:统计字符串数组中所有出现的字符//stream.map(String::toCharArray).forEach(e->System.out.println(Arrays.toString(e)));//结果为 [h, e, l, l, o] [w, o, r, l, d] 两个数组 不符合我们的要求

stream.map(s->s.split(""))

.flatMap(Arrays::stream)

.distinct()

.forEach(System.out::println);//结果为h e l o w r d

}

View Code

6. Collections工具类

Collectors是一个工具类,里面封装了很多方法,可以很方便的获取到一个Collector接口的实现类对象,从而可以使用collect()方法,对流中的数据,进行各种各样的处理、整合。

常用方法:

Collectors.toList()  将流中的数据,聚合到一个List集合中

Collectors.toSet()  将流中的数据,聚合到一个Set集合中

Collectors.toMap()  将流中的数据,聚合到一个Map集合中

maxBy()     按照指定的规则,找到流中最大的元素,等同于max

minBy()     按照指定的规则,找到流中最小的元素,等同于min

joining()     将流中的数据拼接成一个字符串,注意:只能操作流中是String的数据

summingInt()    将流中的数据,映射成int类型的数据,并求和

averagingInt()   将流中的数据,映射成int类型的数据,并求平均值

summarizingInt()   将流中的数据,映射成int类型的数据,并获取描述信息

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public static voidmain(String[] args) {//1. 准备一个字符串数组,作为数据源

String[] dataSource = {"nihao","wo","shi","xxx"};//2. 读取数据源中的数据

Stream stream =Arrays.stream(dataSource);//3. joining方法,只适用于 Stream 这种流//String collect = stream.collect(Collectors.joining());//拼接//System.out.println(collect);//nihaowoshixxx//String collect = stream.collect(Collectors.joining(","));//拼接 按照逗号分隔//System.out.println(collect);//nihao,wo,shi,xxx//tring collect = stream.collect(Collectors.joining(",","[","]"));//拼接 带前缀、后缀//System.out.println(collect);//[nihao,wo,shi,xxx]//4. summingInt

Integer collect =stream.collect(Collectors.summingInt(String::length));

System.out.println(collect);//13

}

View Code

持续更新!!!

注意:本篇文章大多数内容来自bilibili网站千锋教育,地址:https://www.bilibili.com/video/BV1fT4y177ui?p=6  本篇文章仅用于个人学习和总结,如有侵权,联系删除!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值