java8流运算_Java JDK8—Stream流式计算

简介:流是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列,Stream操作是延迟执行的,它不会改变源对象,返回的是新Stream。

1. 创建Stream

A. 创建流:

顺序流:default Stream stream();

并行流:default Stream parallelStream();

B. 由数组创建流:static Stream stream(T[] array);

C. 由值创建流:public static Stream of(T… values);

2. Stream对象的使用

Intermediate(中间操作):将原始的Stream转换为另外一个Stream;

方法

说明

举例

filter

元素过滤,对Stream对象按照指定的Predicate进行过滤,返回的Strema对象中仅包含满足条件的元素

map

[mapToInt]

[mapToLong]

[mapToDouble]

元素一对一转换,使用传入的Function对象对Stream中所有元素进行映射处理,返回的Stream对象中的元素为原元素处理后的结果

flatMap

(flatMapToInt)

(flatMapToLong)

(flatMapToDouble)

元素一对多转换,对Stream对象中的所有元素进行操作,每个元素会有一个或多个结果,然后将所有的元素组合成一个统一的Stream并返回

distinct

元素去重,返回去重后的Stream对象

sorted

[sorted(Comparator super T> comparator)]

元素排序,返回排序后的Stream对象

limit

元素截取,返回有限个元素组成新的Stream对象

skip

元素跳过,抛弃前指定个元素后,使用剩下的元素组成新的Stream对象返回

peek

生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数即引用的方法,当Stream每个元素被消费的时候都会先执行新Stream给定的方法

注意:

A. skip和limit组合可以替代list中subList方法或者实现分页;

B. Comparator比较器

reverseOrder/reversed:顺序反转;nullsFirst/nullsLast:将null值放在第一个/最后一个;comparing/comparingInt/comparingLong/comparingDouble:指定参数类型比较升序;

thenComparing/thenComparingInt/thenComparingLong/thenComparingDouble:多次比较,就是多条件排序

举例:先将businessName字段有值的排在最前面,然后将level字段值大的排在最前面

0d41fc99add49ab84cf3f63294adb072.png

Terminal(终端操作):产生的是一个结果或者其他的复合操作;

方法

说明

forEach

(forEachOrdered)

对所有的元素进行迭代处理,无返回值

toArray

返回所有元素的数组

min

返回所有元素中最小的Optional对象

max

返回所有元素中最大的Optional对象

anyMatch

只要其中一个元素满足传入的Predicate对象时就返回true,否则返回false

allMatch

所有的元素均满足传入的Predicate对象时就返回true,否则返回false

noneMatch

所有的元素均不满足传入的Predicate对象时就返回true,否则返回false

findFirst

返回第一个元素的Optional对象

findAny

返回任意一个元素的Optional对象

count

所有元素个数

collect

根据传入的参数作相关汇聚计算

reduce

使用一个初始化的值,与Stream中的元素一一做传入的二合运算后返回最终的值。每与一个元素做运算后的结果,再与下一个元素做运算

3. Collectors收集器

A. 将流中的数据转成集合类型:toList、toSet、toMap、toCollection;

方法

返回类型

作用

toList

List

把流中元素收集到List中

toSet

Set

把流中元素收集到Set中

toMap

toCollection

Collection

把流中元素收集到创建的集合

B. 将流中的数据(字符串)使用分隔符拼接在一起:joining;

方法

返回类型

作用

joining

String

连接流中每个字符串

C. 对流中的数据求最大值maxBy、最小值minBy、求和summingInt、求平均值averagingInt;

方法

返回类型

作用

maxBy

Option

根据比较器选择最大值

minBy

Option

根据比较器选择最小值

summingInt

(summingLong)

(summingDouble)

Integer

(Long)

(Double)

对流中的元素的整数属性求和

averagingInt

(averagingLong)

(averagingDouble)

Integer

(Long)

(Double)

计算流中元素整数属性的平均值

summariningInt

IntSummaryStatistics

计算流中元素整数属性的统计值

counting

Long

计算流中元素的个数

D. 对流中的数据进行映射处理:mapping;

举例一:见groupingBy中举例一。

E. 对流中的数据分组:groupingBy、partitioningBy;

方法

返回类型

作用

groupingBy

Map>

根据某属性值对流进行分组,属性为K,结果为V

partitioningBy

Map>

根据true或false进行分区

举例一:对Map集合数据按照键值value进行分组,将键key变为集合List

public static voidmain(String[] args) {//将人分成三队(姓名 - 队号)

Map map = new HashMap<>(4);

map.put("zhangsan", 2);

map.put("lisi", 3);

map.put("wangwu", 1);

map.put("xiaohei", 2);

Map> collect =map.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())));

System.out.println(collect.toString());

}

7d29a5a38742ce1b870ff7083b30f2e3.png

举例二:对List集合对象的名称进行分组,取对象值的最大的值为键值

public static voidmain(String[] args) {

List list = new ArrayList<>();

list.add(new NameValuePair("A区", 2));

list.add(new NameValuePair("B区", 3));

list.add(new NameValuePair("A区", 1));

list.add(new NameValuePair("A区", 3));

list.add(new NameValuePair("B区", 2));

list.add(new NameValuePair("C区", 3));

Map collect = list.stream().collect(Collectors.groupingBy(NameValuePair::getName, Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(nameValuePair -> (Integer) nameValuePair.getValue())), option ->(Integer) option.get().getValue())));

System.out.println(collect.toString());

}

0bdfcbe831a8e9cb204bbd9a0a59876b.png

F. 对流中的数据累计计算:reducing;

G. 对流中结果数据进行转换函数:collectingAndThen。

举例一:见groupingBy中举例二。

4. 实际应用中的实例模型

A. 合并Map,若键相同时键值求和,若键不同时就合并

public static voidmain(String[] args) {

Map map1 = new HashMap<>(4);

map1.put("A", 2);

map1.put("B", 3);

map1.put("C", 4);

Map map2 = new HashMap<>(4);

map2.put("A", 5);

map2.put("B", 3);

map2.put("C", 7);

Map map3 = new HashMap<>(4);

map3.put("D", 5);

map3.put("B", 6);

map3.put("C", 9);

Map map4 = new HashMap<>(4);

map4.put("D", 5);

map4.put("B", 1);

map4.put("E", 9);

Map> map5 = new HashMap<>(3);

map5.put("AA", map1);

map5.put("BB", map2);

Map> map6 = new HashMap<>(3);

map6.put("AA", map3);

map6.put("CC", map4);//Map中键相同时,键值求和;没有时,合并

Map> map7 = Stream.of(map5, map6).flatMap(map ->map.entrySet().stream()).collect(Collectors.toMap(

Map.Entry::getKey,

Map.Entry::getValue,

(v1, v2)-> Stream.of(v1, v2).flatMap(map ->map.entrySet().stream()).collect(Collectors.toMap(

Map.Entry::getKey,

Map.Entry::getValue,

(v3, v4)-> v3 +v4

))

));

System.out.println(map7.toString());

}

522caf86bf15c3c46d34e007302a3e1e.png

B. 基于A条件,Map取键值最大的前三个并按逗号拼接成字符串

Map map8 =map7.entrySet().stream().collect(Collectors.toMap(

Map.Entry::getKey,

entry-> entry.getValue().entrySet().stream().sorted(Map.Entry.comparingByValue().reversed())

.limit(3).map(Map.Entry::getKey).collect(Collectors.joining(","))

));

System.out.println(map8.toString());

7bbdab3ec5c97b286de7b34e53455d2e.png

C. 对List集合进行条件分类,然后符合相应条件的进行求和

public static voidmain(String[] args) {

User user1= newUser();

user1.setId(1L);

user1.setRoleId(2L);

User user2= newUser();

user2.setId(3L);

user2.setRoleId(4L);

User user3= newUser();

user3.setId(5L);

user3.setRoleId(8L);

User user4= newUser();

user4.setId(4L);

user4.setRoleId(6L);

List list = new ArrayList<>();

list.add(user1);

list.add(user2);

list.add(user3);

list.add(user4);

Map map = list.stream().collect(Collectors.groupingBy(user ->{if (user.getId() < 2L) {return 1;

}else if (user.getId() < 6L) {return 2;

}else{return 3;

}

}, Collectors.summingLong(User::getRoleId)));

System.out.println(map.toString());

}

65a0c304d8cb3ad66d6342a9d0312157.png

D.  取Map集合中键最大的键

public static voidmain(String[] args) {

Map map1 = new HashMap<>(3);

map1.put(1, 2L);

map1.put(2, 5L);

Map map2 = new HashMap<>(3);

map2.put(3, 4L);

map2.put(2, 5L);

Map> map3 = new HashMap<>(3);

map3.put("A", map1);

map3.put("B", map2);

Map map =map3.entrySet().stream().collect(Collectors.toMap(

Map.Entry::getKey,

entry->entry.getValue().entrySet().stream().max(Map.Entry.comparingByKey()).get().getKey()

));

System.out.println(map.toString());

}

7d39dec4ae916281a9ae94db122bd53e.png

E. 多个Map, 键值合并为对象

public static voidmain(String[] args) {

Map map1 = new HashMap<>(4);

map1.put("A", "WE");

map1.put("B", "RT");

map1.put("C", "lo");

Map map2 = new HashMap<>(4);

map2.put("D", 12L);

map2.put("B", 34L);

map2.put("C", 67L);

Map map3 = new HashMap<>(4);

map3.put("B", 11L);

map3.put("E", 50L);

map3.put("C", 87L);

Map map4 = Stream.of(map1, map2, map3).flatMap(map ->map.entrySet().stream()).collect(Collectors.toMap(Map.Entry::getKey,

v-> new UserDemo(map1.getOrDefault(v.getKey(), null), map2.getOrDefault(v.getKey(), null), map3.getOrDefault(v.getKey(), null)),

(v1, v2)-> newUserDemo(v1.getUsername(), v1.getRoleId(), v1.getPermissionId())

));

System.out.println(map4.toString());

}

64381c09b822929ed7551f693e43d7f9.png

F. 对Map集合及Map集合中键值Map进行过滤

public static voidmain(String[] args) {

Map map1 = new HashMap<>(3);

map1.put("1", 4);

map1.put("2", 3);

Map map2 = new HashMap<>(3);

map2.put("2", 6);

map2.put("3", 4);

Map map3 = new HashMap<>(4);

map3.put("1", 7);

map3.put("2", 9);

map3.put("3", 4);

Map> map = new HashMap<>(4);

map.put("A", map1);

map.put("B", map2);

map.put("C", map3);

Map> collect =map.entrySet().stream()

.filter(entry-> entry.getValue().containsKey("1"))

.collect(Collectors.toMap(

Map.Entry::getKey,

entry->entry.getValue().entrySet().stream()

.filter(entry1-> "1".equals(entry1.getKey()))

.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));

System.out.println(collect.toString());

}

476a8ad1599338840a74acf598f69bc4.png

F. List数据分批处理切割

public static voidmain(String[] args) {

List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);//最大数量

int maxSize = 3;//切分次数

int limit = (list.size() + maxSize - 1) /maxSize;

List> lists = Stream.iterate(0, n -> n + 1)

.limit(limit)

.map(a->list.stream()

.skip(a*maxSize)

.limit(maxSize)

.collect(Collectors.toList()))

.collect(Collectors.toList());

lists.forEach(list1->{

System.out.println("个数:" +list1.size());

list1.forEach(System.out::println);

System.out.println("遍历完毕");

});

}

9af7ccc6c98eaf42ab94bfbac50508d8.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值