美文网首页
八股一下:List集合常用的10多种数据处理用法

八股一下:List集合常用的10多种数据处理用法

作者: 程就人生 | 来源:发表于2023-12-25 21:06 被阅读0次

最近一直在忙老项目的升级改造,在处理数据的时候,突然想使用某个方法,隐隐约约记得,怎么写的却忘了。忘记了就要重新翻文档或搜索,非常麻烦。怎么办呢,那就抽时间整理一下吧,于是便有了此文。

List集合的各种处理

有一个List集合,里面装着UserInfo对象,对象里有用户uid、性别sex、年龄age、姓名userName等属性。

// 模拟一组用户数据
List<UserInfo> userInfoList = new ArrayList<UserInfo>(20);
UserInfo userInfo;
for(int i=1;i<10;i++){
  userInfo = new UserInfo();
  userInfo.setUserUid(i+ "");
  userInfo.setUserName("用户"+i);
  userInfo.setAge(i);
  // 性别各一半
  userInfo.setSex((byte) (i%2));
  userInfoList.add(userInfo);
}
// 打印原数据
userInfoList.forEach(item->{logger.info("原数据:{}",item.toString());});

1、过滤List集合的对象,只保留sex为0的对象,并返回一个新的集合。

// 用法1:过滤 filter,只保留sex==0的数据    
List<UserInfo> userInfoList1 = userInfoList.stream().filter(item->item.getSex()==0).collect(Collectors.toList());    
userInfoList1.stream().forEach(item->{logger.info("保留的数据:{}",item.toString());});

打印结果:

22:24:24.052 [main] INFO com.test.other.TestStream - 原数据:UserInfo [userUid=4, age=4, sex=0, userName=用户4]
22:24:24.052 [main] INFO com.test.other.TestStream - 原数据:UserInfo [userUid=5, age=5, sex=1, userName=用户5]
22:24:24.052 [main] INFO com.test.other.TestStream - 原数据:UserInfo [userUid=6, age=6, sex=0, userName=用户6]
22:24:24.052 [main] INFO com.test.other.TestStream - 原数据:UserInfo [userUid=7, age=7, sex=1, userName=用户7]
22:24:24.052 [main] INFO com.test.other.TestStream - 原数据:UserInfo [userUid=8, age=8, sex=0, userName=用户8]
22:24:24.052 [main] INFO com.test.other.TestStream - 原数据:UserInfo [userUid=9, age=9, sex=1, userName=用户9]
22:24:24.065 [main] INFO com.test.other.TestStream - 保留的数据:UserInfo [userUid=2, age=2, sex=0, userName=用户2]
22:24:24.066 [main] INFO com.test.other.TestStream - 保留的数据:UserInfo [userUid=4, age=4, sex=0, userName=用户4]
22:24:24.066 [main] INFO com.test.other.TestStream - 保留的数据:UserInfo [userUid=6, age=6, sex=0, userName=用户6]
22:24:24.066 [main] INFO com.test.other.TestStream - 保留的数据:UserInfo [userUid=8, age=8, sex=0, userName=用户8]

// 使用filter对脏数据的过滤
userInfoList.stream().filter(Objects::nonNull).forEach(item->{logger.info("过滤脏数据:{}",item.toString());});

2、找出符合条件的第一个对象,没有返回null。

// 用法2:找出符合条件的第一个对象,没有返回null
userInfo = userInfoList.stream().filter(item->item.getAge()==8).findFirst().orElse(null);
logger.info("符合条件的第一个对象,没有返回null:{}",userInfo);

执行结果:

22:28:06.949 [main] INFO com.test.other.TestStream - 符合条件的第一个对象,没有返回null:UserInfo [userUid=8, age=8, sex=0, userName=用户8]

3、根据性别对集合进行分组,返回Map集合,每种性别个对应一个集合。

// 用法3:根据某个字段对集合排序,并以排序字段为key,存到map集合里 Collectors.groupingBy()
// 使用场景:把用户按照男女分成两组
Map<Byte, List<UserInfo>> userInfoMap = userInfoList.stream().collect(Collectors.groupingBy(item->item.getSex()));
logger.info("获取性别为0的数据数量:{}",userInfoMap.get((byte)0).size());
// 
userInfoMap.keySet().forEach(item->logger.info("性别遍历{}",item));

执行结果:

22:30:26.901 [main] INFO com.test.other.TestStream - 获取性别为0的数据数量:4
22:30:26.906 [main] INFO com.test.other.TestStream - 性别遍历0
22:30:26.906 [main] INFO com.test.other.TestStream - 性别遍历1

// 如何把key变为String类型的
Map<String, List<UserInfo>> userInfoMap1 = userInfoList.stream().collect(Collectors.groupingBy(item->item.getSex().toString()));
logger.info("获取性别为0的数据数量:{}",userInfoMap1.get("0").size());

4、从集合中抽出对象的某一属性,并创建一个新的集合。

// 用法4:从对象集合里获取用户uid集合,map()+collect()
List<String> userUids = userInfoList.stream().map(item->item.getUserUid()).collect(Collectors.toList());
//List<String> userUids = userInfoList.stream().map(UserInfo::getUserUid).collect(Collectors.toList());
logger.info("从对象集合里获取用户uid集合:{}",userUids);

执行结果:

22:34:03.948 [main] INFO com.test.other.TestStream - 从对象集合里获取用户uid集合:[1, 2, 3, 4, 5, 6, 7, 8, 9]

5、从集合中抽出对象的某一属性,并创建一个新的集合,同时保证不重复。

// 用法5:获取单个数据的不重复集合,使用Set的集合特性
Set<Byte> sexs = userInfoList.stream().map(UserInfo::getSex).collect(Collectors.toSet());
logger.info("用户里的性别种类有:{}",sexs);
   
//    // 用法5:获取单个数据的不重复集合,使用distinct方法
//    List<Byte> sexs1 = userInfoList.stream().map(UserInfo::getSex).distinct().collect(Collectors.toList());
//    logger.info("2用户里的性别种类有:{}",sexs1);

执行结果:

22:37:34.994 [main] INFO com.test.other.TestStream - 用户里的性别种类有:[0, 1]

6、获取集合中符合条件的对象,如果存在,并做一些事情。

// 用法6:对集合里符合条件的第一个对象的某个字段做些事情,ifPresent
userInfoList.stream().filter(item->item.getAge()==5).findFirst().ifPresent(item->item.setAge(15));
logger.info("被处理的数据:{}",userInfoList.stream().filter(item->item.getAge()==15).findFirst())

执行结果:

22:39:54.889 [main] INFO com.test.other.TestStream - 被处理的数据:Optional[UserInfo [userUid=5, age=15, sex=1, userName=用户5]]

7、从集合里匹配、或不匹配符合条件的对象属性,返回布尔值。

// 用法9:从对象集合里去查找是否存在某个元素为指定值,找到即返回
boolean isExists = userInfoList.stream().anyMatch(item->item.getAge()==15);
logger.info("是否存在年龄字段为5的数据:{}", isExists);

// noneMatch没有匹配的返回true,否则返回false
logger.info("队列里是否有年龄为20的:{}", userInfoList.stream().noneMatch(item->item.getAge()==20));

执行结果:

22:47:31.580 [main] INFO com.test.other.TestStream - 是否存在年龄字段为5的数据:false
22:47:31.585 [main] INFO com.test.other.TestStream - 队列里是否有年龄为20的:true

8、给一个对象,返回一个集合。

// 用法10:给一个对象,返回一个list集合,singleton返回set集合
List<String> str = Collections.singletonList("aaa");
logger.info("list集合:{}", str);

执行结果:

22:49:01.029 [main] INFO com.test.other.TestStream - list集合:[aaa]

9、抽取、排序、过滤、遍历组合使用。

// 对属性进行排序
userInfoList.stream()
.map(UserInfo::getSex)
.sorted(Comparator.comparing(obj -> obj))
.forEach(item->logger.info("数据:{}",item));

// 根据属性对对象进行排序
userInfoList.stream()
.filter(Objects::nonNull)
// 进行排序,按照pushDate升序
.sorted(Comparator.comparing(UserInfo::getSex))
.forEach(item->logger.info("数据:{}",item.toString()));

执行结果:

21:00:37.028 [main] INFO com.test.other.TestStream - 数据:0
21:00:37.032 [main] INFO com.test.other.TestStream - 数据:0
21:00:37.032 [main] INFO com.test.other.TestStream - 数据:0
21:00:37.032 [main] INFO com.test.other.TestStream - 数据:0
21:00:37.032 [main] INFO com.test.other.TestStream - 数据:1
21:00:37.033 [main] INFO com.test.other.TestStream - 数据:1
21:00:37.033 [main] INFO com.test.other.TestStream - 数据:1
21:00:37.033 [main] INFO com.test.other.TestStream - 数据:1
21:00:37.033 [main] INFO com.test.other.TestStream - 数据:1
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=2, age=2, sex=0, userName=用户2]
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=4, age=4, sex=0, userName=用户4]
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=6, age=6, sex=0, userName=用户6]
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=8, age=8, sex=0, userName=用户8]
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=1, age=1, sex=1, userName=用户1]
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=3, age=3, sex=1, userName=用户3]
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=5, age=5, sex=1, userName=用户5]
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=7, age=7, sex=1, userName=用户7]
21:00:37.036 [main] INFO com.test.other.TestStream - 数据:UserInfo [userUid=9, age=9, sex=1, userName=用户9]

10、Collectors工具类的使用汇总

在上面的很多数据处理中,我们都离不开Collectors工具类,再把Collectors的使用汇总下:

// 1、把集合中对象的某个属性单独抽离出来作为一个新的集合

List<String> list = userInfoList.stream().map(UserInfo::getUserName).collect(Collectors.toList());
logger.info("list:{}",list);

// 2、返回一个不重复的集合

Set<String> set = userInfoList.stream().map(UserInfo::getUserName).collect(Collectors.toCollection(TreeSet::new));
logger.info("set:{}",set);

// 3、把一个集合的某个属性提前为一个字符串

String joined = userInfoList.stream()
                      .map(UserInfo::getUserName) //Object::toString
                      .collect(Collectors.joining(", "));
logger.info("joined:{}",joined);

// 4、对集合里对象的某个Integer属性求和

int total = userInfoList.stream()
                     .collect(Collectors.summingInt(UserInfo::getAge));
logger.info("total:{}",total);

// 5、分组,通过集合中某个对象的属性进行分组

Map<Byte, List<UserInfo>> bySex
    = userInfoList.stream()
               .collect(Collectors.groupingBy(UserInfo::getSex));
logger.info("bySex:{}",bySex);

// 6、计算,每种性别,各自年龄的总和

Map<Byte, Integer> totalBySex
    = userInfoList.stream()
               .collect(Collectors.groupingBy(UserInfo::getSex,Collectors.summingInt(UserInfo::getAge)));
logger.info("totalBySex:{}",totalBySex);

// 7、根据条件获取部分用户

Map<Boolean, List<UserInfo>> passingFailing =
    userInfoList.stream()
            .collect(Collectors.partitioningBy(s -> s.getAge() >= 5));
logger.info("passingFailing:{}",passingFailing);

11、求和,和10的求和有点区别。

// 用法11:求和
List<BigDecimal> numberList = new ArrayList<BigDecimal>();
numberList.add(new BigDecimal(10));
numberList.add(new BigDecimal(5));
logger.info("BigDecimal的list求和:{}", numberList.stream().reduce((x, y) -> x.add(y)).orElse(BigDecimal.ZERO));

// 把BigDecimal集合转换成String型集合
List<String> numberList1 = numberList.stream().map(BigDecimal::toString).map(String::trim).collect(Collectors.toList());

List<Integer> ls = new ArrayList<>();
ls.add(4);ls.add(2);ls.add(6);
logger.info("list先排序,转数组{},{}", ls.stream().sorted().mapToInt(i -> i).toArray(), ls.toArray());
        
Integer[] arr = new Integer[5];
arr[0] = 5;
logger.info("过滤前的数组{},对象:{}", arr,arr.toString());
// 过滤为null的数据,并返回一个新的数组
arr = Arrays.stream(arr).filter(Objects::nonNull).toArray(Integer[]::new);
logger.info("过滤后的数组{},对象{}", arr,arr.toString());

运行结果:

21:21:45.485 [main] INFO com.test.other.TestStream - BigDecimal的list求和:15
21:21:45.502 [main] INFO com.test.other.TestStream - list先排序,转数组[2, 4, 6],[4, 2, 6]
21:21:45.502 [main] INFO com.test.other.TestStream - 过滤前的数组[5, null, null, null, null],对象:[Ljava.lang.Integer;@3f8f9dd6
21:21:45.507 [main] INFO com.test.other.TestStream - 过滤后的数组[5],对象[Ljava.lang.Integer;@726f3b58

12、字符串数组,转为不重复集合。

// 字符串数组,转为不重复集合
String str1="aaa,bbb,ccc,ddd,aaa";
String[] arr = str1.split(",");
logger.info("不重复数组集合数量:{}", Arrays.stream(arr).distinct().count());
Set<String> set = Arrays.stream(arr).collect(Collectors.toSet());
// Arrays.asList(arr);
logger.info("不重复数组集合:{}", set);
List<String> str = Arrays.stream(arr).distinct().collect(Collectors.toList());
logger.info("不重复数组集合:{}", str);

// 将字符串集合转换为字符串
str1 = str.stream().collect(Collectors.joining("','", "('", "')"));
logger.info("拼接的字符串:{}", str1);

运行结果:

22:15:04.514 [main] INFO com.test.other.TestStream - 不重复数组集合数量:4
22:15:04.526 [main] INFO com.test.other.TestStream - 不重复数组集合:[aaa, ccc, bbb, ddd]
22:15:04.527 [main] INFO com.test.other.TestStream - 不重复数组集合:[aaa, bbb, ccc, ddd]
22:15:04.530 [main] INFO com.test.other.TestStream - 拼接的字符串:('aaa','bbb','ccc','ddd')

以上便是本次的整理,希望对你有帮助。

相关文章

  • java基础-day16-list集合

    List集合 1. List集合 1.1 List集合特征 1.2 List常用方法 2. ArrayList 可...

  • 面试聊几句

    一.常用的集合 Collection下的List集合的话有ArrayList和LinkedList,Set集合常用...

  • java五个常用集合区别和联系

    常用的集合类有一下几种: List结构的集合类:ArrayList类,LinkedList类,Vector类,St...

  • Collections工具类

    常用方法 reverse(List):反转 List 中元素的顺序 shuffle(List):对 List 集合...

  • Flutter学习笔记1.4 Dart基础(List Set M

    List集合数据操作 List里面常用的属性和方法:常用属性:length 长度reversed ...

  • Java容器:List

    集合类的层次关系 List接口简介 List的常用方法 List实例VectorArrayListVector和A...

  • Dart基础:可迭代的集合

    Dart中的集合类型 Dart中常用的集合类型:List、Set、Map。其中List、Set实现了Iterabl...

  • Java基础

    集合 介绍一下集合框架?常用类及其方法? List接口、Set接口和Map接口的区别? 说出ArrayList,V...

  • kotlin中的集合

    集合Java中常用的集合主要是List、Set和Map接口,List的实现类是ArrayList和LinkedLi...

  • java集合学习总结

    集合的根接口:Collection和 Map Collection接口的常用子接口:List, Set List接...

网友评论

      本文标题:八股一下:List集合常用的10多种数据处理用法

      本文链接:https://www.haomeiwen.com/subject/ntbhndtx.html