java 函数式编程 流式计算 小白必看


加油


Stream背景

Java 8的一大亮点Stream,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。

Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。

Stream API 借助于同样新出现的 Lambda 表达式,极大地提高编程效率和程序可读性。

同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。


Stream有什么好处?

  • 有高效率的并行操作
  • 有很多种功能性的聚合操作
  • 函数式编程,使代码更加简洁,提高编程效率


Stream的操作 可以分为两大类:中间操作、中介操作


当我们使用一个流程的时候,通常包括三个基本步骤:

获取一个数据源(source)→ 数据转换 → 执行操作获取想要的结果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道。

List list = Arrays.asList("hello","world","stream");//创建顺序流Stream stream = list.stream();//创建并行流Stream parallelStream = list.parallelStream();



stream是顺序流,由主线程按顺序对流执行操作,

parallelStream是并行流,内部以多线程并行执行的方式对流程进行操作,需要注意

使用并行流parallelStream的前提是流中的数据处理没有顺序要求(会乱序,即使用了forEachOrdered)。



使用demo:

----------------------------------reduce

this.doTotalCount = countDoHeaderMap.values().stream().reduce(Integer::sum).orElse(0);

---------------------中间操作 filter 过滤器

public void testFilter(){

// 筛选出年龄大于14岁的user

userStream().filter(user -> user.getAge() > 14).forEach(System.out::println);

// 遍历: User(name=卡诺5, age=15, gender=0)

}


-----------------------------------------distinct 去重

distinct:返回由该流的不同元素组成的流(根据 Object.equals(Object));

distinct()使用hashCode()和equals()方法来获取不同的元素。

因此,我们的类必须实现hashCode()和equals()方法。

public void testDistinct(){

Stream.of(1, 1, 3, 2, 3).distinct().forEach(System.out::print);

// 132

}


-------------------------------------------map

// 映射出所有名字

public void testMap(){

userStream().map(User::getName).forEach(System.out::print);

// 卡诺1卡诺2卡诺3卡诺4卡诺5

}

----------------------------------------------max

public void testMax() {

Integer max = Stream.of(1, 2, 3, 4).max(Comparator.comparingInt(t -> t)).get();

System.out.println(max);

// 4

}

--------------------------------------min

public void testMin() {

Integer min = Stream.of(1, 2, 3, 4).min(Comparator.comparingInt(t -> t)).get();

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

}





sorted:返回由该流的元素组成的流,并根据自然顺序排序

该接口有两种形式:无参和有参数,如:

Stream sorted();

Stream sorted(Comparator<? super T> comparator);


sorted demo1:---------------------------------------------------------

// 增加一个比较器,按照年龄降序

// 获取排序后的第一个数据

// 遍历: User(name=卡诺5, age=15, index=0)

user.stream()

.sorted((u1, u2) -> u2.getAge() - u1.getAge())

.limit(1).forEach(System.out::println);

sorted demo2:---------------------------------------------------------

List collect =

//把流中所有元素收集到List中 Collectors.toList()

resultList.stream()

.sorted(Comparator.comparing(LocationDTO::getDistance))

.collect(Collectors.toList());


sorted demo3:---------------------------------------------------------

//1.准备一个List集合

ArrayList list = new ArrayList<>();

list.add("200");

list.add("1");

//2.获取Stream对象

Stream streamList01 = list.stream();

Stream streamList02 = list.stream();

//3.将元素 按照数字大小 升序排列

streamList01

.map(Integer::parseInt) // 先把字符串转成数字

.sorted() // 默认升序的方式

.forEach(System.out::println);

//3.将元素 按照数字大小 自定义顺序排列 : 降序

streamList02

.map(Integer::parseInt) // 先把字符串转成数字

.sorted((o1,o2) -> o2-o1) // 重写 Comparator 接口的compare方法,自定义比较的顺序 : 降序排列

.forEach(System.out::println);






collect:称为收集器

  • 是一个终端操作,它接收的参数是将流中的元素累积到汇总结果的各种方式

Collectors.groupingBy

receiveLogs 集合 通过 Collectors.groupingBy 转换成

map> 的 格式:

List receiveLogs ;

//示例:Map> menuType

// = Menu.getMenus.stream().collect(groupingby(Menu::getType));

//根据流中元素的某个值 对 流中的元素进行分组, 并将属性值 做为结果map的键

receiveLogs.stream().collect( Collectors.groupingBy(ReceiveLogDto::getDocLineId) )

-------------------------------------------------------------------------------------------------------



Collectors.toMap

skuDtos 集合 转换成 map 的 格式

使用toMap()函数之后,返回的就是一个Map了,自然会需要key和value。

//在.collect(Collectors.toMap(SkuOuterDto::getId, v -> v, (a,b)->a))中:

toMap()的

第一个参数就是用来生成key值的,

第二个参数就是用来生成value值的。

第三个参数用在key值冲突的情况下:如果新元素产生的key在Map中已经出现过了,

第三个参数就会定义解决的办法。



第一个参数:SkuOuterDto:getId表示选择SkuOuterDto的getId作为map的key值;

第二个参数:v->v表示选择将原来的对象作为Map的value值

第三个参数:(a,b)->a中,如果a与b的key值相同,选择a作为那个key所对应的value值。


List skuDtos = PlainResultUtil.unbox(skuOuterApi.listByIdList(skuIdList));

if(CollectionUtils.isNotEmpty(skuDtos)){

Map skuOuterDtoMap =

skuDtos.stream().collect(

Collectors.toMap(SkuOuterDto::getId, Function.identity(), (key1, key2) -> key2)

);

}

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章