一些常用的Stream流和Lambda表达式的结合

一.将一个对象集合中的某个属性转换为一个集合

List<T> propertyList = DOList.stream().map(DO::getProperty).collect(Collectors.toList());

1.如果获取的属性需要进行类型转换

例:List<Integer> propertyList = DOList.stream( ).map(v -> Integer.valueOf(v.getProperty())).collect(Collectors.toList());

2.如果在进行类型转换时有空值则会报错(需排除空值)
(以String类型转换为Integer为例,map和 filter可以视情况交换使用顺序)

例:List<Integer> propertyList= DOList.stream()
                .filter(v -> v.getProperty() != null && !"".equals(v.getProperty ()))
                .map(v -> Integer.valueOf(v.getProperty()))
                .collect(Collectors.toList());

3.转换集合时只保留另外一个集合(list)中存在的值

例:List<Integer> propertyList = DOList.stream()
                .filter(v -> list.contains(v.getProperty()))
                .map(v -> Integer.valueOf(v.getProperty()))
                .collect(Collectors.toList());

4.将一个集合转换成字符串用","隔开

例:String string = list.stream().collect(Collectors.joining(","));
(如果是转换对象集合中的一个属性,则可以使用map映射到这个属性再collect)

二.将一个对象集合的属性和对象自身转换为一个Map集合

注:(Function.identity() 可替换为 x -> x)

例:Map<T, DO> DOMap = DOList.stream().collect(Collectors.toMap(DO::getProperty, Function.identity()));

1.当集合(DOList)中存在重复值,转换为Map时会因为key重复而报错:Duplicate key(解决方法:合并key)

1.用后面的 value 覆盖前面的 value
例:Map<T,DO> DOMap = DOList.stream().collect(Collectors.toMap(DO::getProperty, Function.identity(), (k1,k2) -> k2));

2.将前面的 value 和后面的value拼接起来
例:Map<T,T> propertyMap = DOList.stream().collect(Collectors.toMap(DO::getProperty1, DO::getProperty2, (k1,k2) -> k1+","+k2));

3.合并 list 集合为一个集合
例:Map<T,List<T>> listMap = DOList.stream().collect(Collectors.toMap(DO::getProperty, DO::getList, (List<T> list1,List<T> list2) -> {list1.addAll(list2);return list1;}));

4.合并 指定属性值 为一个集合
Map<T,List<T>> listMap = 
DOList.stream().collect(Collectors.groupingBy(DO::getProperty1, Collectors.mapping(DO::getProperty2, Collectors.toList())));

2.当需要根据集合(DOList)中某个属性进行分组时,可以使用 Collectors.groupingBy()

1.Collectors.groupingBy() 可以嵌套使用
例:Map<T, Map<T, List<DO>>> DOMap = DOList.stream()
                    .collect(Collectors.groupingBy(DO::getProperty1,
                            Collectors.groupingBy(DO::getProperty2)));

2.Collectors.groupingBy() 可以和 Collectors.toMap() 结合使用
例:Map<T, Map<T, T>> DOMap = DOList.stream()
                    .collect(Collectors.groupingBy(DO::getProperty1,
                            Collectors.toMap(DO::getProperty2, DO::getProperty3,
                                    (k1, k2) -> new BigDecimal(k1).add(new BigDecimal(k2)).toString())));
<!-- 注:这里以 DO 中 property3 属性为数值字符串时,进行对数值字符串类型的聚合 -->

3.对象集合根据某个属性分组的map根据键值进行排序
List<Map.Entry<T, List<DO>>> sectionDOList = DOMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toList());

三.对象集合中某一属性相关统计(求和、最大、最小、平均)

1.求和
double sum = DOList.stream().mapToDouble(DO::getProperty).sum();
2.最大值
double max = DOList.stream().mapToDouble(DO::getProperty).max();
3.最小值
double min = DOList.stream().mapToDouble(DO::getProperty).min();
4.平均值
double ave = DOList.stream().mapToDouble(DO::getProperty).average();

#注:除了 mapToDouble(),还有 mapToInt ()、mapToLong();

1.遇到统计 BigDecimal 类型的数据

1.求和
BigDecimal sum = DOList.stream().map(DO::getProperty).reduce(BigDecimal.ZERO, BigDecimal::add);
2.最大值
BigDecimal max = DOList.stream().map(DO::getProperty).max(BigDecimal::compareTo).get();
3.求最小值
BigDecimal min = DOList.stream().map(DO::getProperty).min(BigDecimal::compareTo).get();
4.求平均值
BigDecimal ave = DOList.stream().map(User::getProperty).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(DOList.size()), 2, BigDecimal.ROUND_HALF_UP);

四.Stream流使用

1.筛选

  • filter(boolean):过滤(boolean为true时往后执行);
  • distinct():去重;
  • limit(n):截短流(只获取符合条件的 n 条数据);
  • skip(n):跳过元素(跳过满足条件的前 n 条数据);

2.映射

  • map:将一个类型元素转为另一个类型的元素;
  • flatMap:把一种流转成另一种流,并将转换后的流合并成一个流;

3.查找和匹配

  • allMatch(boolean):是否匹配所有元素;
  • anyMatch(boolean):是否匹配至少一个元素;
  • noneMatch(boolean):是否没有任何元素匹配;
  • findFirst():返回流中的第一个元素;
  • findAny():返回流中的任意一个元素;
  • reduce(a, b):a(是总变量的初始值),b(函数式接口的实现类,一般使用Lambda表达式);

4.改变内部元素

  • peek():可用于修改集合中的属性,可用于输出信息

五. 根据对象集合中的某个属性对这个集合进行"排序/去重"

1. 排序
sorted():它使用自然顺序对流的元素进行排序。元素类必须实现Comparable接口

集合排序
1_1 集合升序排序
list.stream().sorted().collect(Collectors.toList());
1_2 集合降序排序,自然序降序使用Comparator提供reverseOrder()方法
list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

对象集合排序
2_1 对象集合按某一属性升序排序
DOList.stream().sorted(Comparator.comparing(DO::getProperty)).collect(Collectors.toList());
2_2 对象集合按某一属性降序排序,使用Comparator提供reversed()方法
DOList.stream().sorted(Comparator.comparing(DO::getProperty).reversed()).collect(Collectors.toList());

附加:
对象集合根据某个属性排序(属性为字符串类型数值)
3_1 正序
DOList.sort((o1, o2) -> Integer.compare(Integer.valueOf(o1.getProperty()), Integer.valueOf(o2.getProperty())));
3_2 倒叙
DOList.sort((o1, o2) -> -1 * Integer.compare(Integer.valueOf(o1.getProperty()), Integer.valueOf(o2.getProperty())));

2. 去重
使用Comparator.comparing获取到指定去重属性,TreeSet实现去重
注:Comparator还有"comparingInt()"、"comparingLong()"、"comparingDouble()"

ArrayList::new用来转换结果为List集合
List<DO> DODistinctList = DOList.stream()
        .collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(DO::getProperty))), ArrayList::new));

也可以直接去重之后转化为Set
Set<DO> DOSet = DOList.stream().collect(Collectors.toCollection(
        () -> new TreeSet<>(Comparator.comparing(DO::getProperty))));
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351