Java8 List Stream常用操作总结记录

项目中经常会用到 list.stream() 的操作,比如说比较两个list、list分组统计、筛选、转map这些,有的时候不太熟练的就经常会忘记要怎么写,还得翻以前的代码看看是怎么写的。所以干脆把用过的都总结记录起来,以后忘了的话就不用打开这个项目那个项目翻代码了。

先创建两个list并添加好数据

@Data
public static class Entity{
    
    
   private int id;
   private String name;
   private String attribute;
   private String type;

   public Entity(){
    
    }

   public Entity(int id,String name,String attribute,String type){
    
    
       this.id = id;
       this.name = name;
       this.attribute = attribute;
       this.type = type;
   }
}

private static List<Entity> list1 = new ArrayList<>();
private static List<Entity> list2 = new ArrayList<>();

static {
    
    
   list1.add(new Entity(1,"迅羽","异能","雷伤"));
   list1.add(new Entity(2,"炽翎","异能","火伤"));
   list1.add(new Entity(3,"月轮","机械","雷伤"));
   list1.add(new Entity(4,"白夜","生物","物伤"));
   list1.add(new Entity(5,"云墨","异能","火伤"));
   list1.add(new Entity(6,"识宝","生物","物伤"));

   list2.add(new Entity(1,"迅羽","异能","雷伤"));
   list2.add(new Entity(3,"影骑士月轮","机械","雷伤"));
   list2.add(new Entity(5,"云墨丹心","异能","火伤"));
   list2.add(new Entity(6,"识宝","生物","火伤"));
   list2.add(new Entity(7,"理律","机械","冰伤"));
   list2.add(new Entity(8,"空律","生物","物伤"));
   list2.add(new Entity(9,"雷律","异能","雷伤"));
   list2.add(new Entity(10,"炎律","异能","火伤"));
}

1、list转map

// 以id为key,实体对象为value
Map<Integer, Entity> map1 = list1.stream().collect(Collectors.toMap(Entity::getId, Function.identity(), (key1, key2) -> key2));

// 以某个属性或多个属性为key,某个属性值为value
Map<String, String> map2 = list1.stream().collect(Collectors.toMap(item -> fetchGroupKey(item), Entity::getAttribute));

/**
 * 多个属性用 # 号分隔
 */
private String fetchGroupKey(Entity entity){
    
    
    return entity.getId() +"#" +entity.getName();
}

在这里插入图片描述

2、获取指定属性值,并转为对应的list:获取list2中所有name,并转为list

List<String> nameList = list2.stream().map(Entity::getName).collect(Collectors.toList());

3、list根据指定属性过滤数据:只保留attribute为生物的元素

List<Entity> filterResult = list2.stream().filter(item -> "生物".equals(item.getAttribute())).collect(Collectors.toList());

在这里插入图片描述

4、list取交集

//  4.1 根据整个元素取交集,这里需要元素的全部属性值相同
List<Entity> intersection1 = list1.stream().filter(item -> list2.contains(item)).collect(Collectors.toList());

//  4.2 根据某个属性或多个属性值取交集:根据id和name
List<Entity> intersection2 = list1.stream().filter(item -> list2.parallelStream().anyMatch(tm->item.getId() == tm.getId() 
&& item.getName().equals(tm.getName()))).collect(Collectors.toList());

在这里插入图片描述

5、list取差集

//  5.1 根据整个元素取差集
List<Entity> reduce1 = list1.stream().filter(item -> !list2.contains(item)).collect(Collectors.toList());

//  5.2 根据属性取差集:根据id,在list1中过滤出list2没有的数据(可以有多个属性)
List<Entity> reduce2 = list1.stream().filter(item -> (list2.parallelStream().noneMatch(tm -> 
item.getId() == tm.getId()))).collect(Collectors.toList());

在这里插入图片描述

6、list取并集并去重

// 必须要元素的全部相同才能去重
List<Entity> union = Stream.of(list1, list2).flatMap(Collection::stream).distinct().collect(Collectors.toList());

在这里插入图片描述

7、list去重

// 7.1 用distinct:必须要元素的全部相同才能去重
List<Entity> unique1 = list1.stream().distinct().collect(Collectors.toList());

// 7.2 用TreeSet:根据attribute去重
List<Entity> unique2 = list1.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(o -> o.getAttribute()))), ArrayList::new));

/**
 * 7.3 用toMap:
 * oldValue、newValue代表旧值、新值。
 * 当stream构造Map时,会先调用Map的get方法获取该key对应的旧值,如果该值为null,则不会调用BinaryOperator函数;
 * 如果不为null,则会把获取的旧值与新值作为参数传给函数执行,然后把函数的返回值作为新值put到Map中。
 */
// 这里是把oldValue作为函数返回值
List<Entity> unique3 = new ArrayList<>(list1.stream()
        .collect(Collectors.toMap(Entity::getAttribute, Function.identity(), (oldValue, newValue) -> oldValue)).values());

// 这里是把newValue作为函数返回值
List<Entity> unique4 = new ArrayList<>(list1.stream()
        .collect(Collectors.toMap(Entity::getAttribute, Function.identity(), (oldValue, newValue) -> newValue)).values());

在这里插入图片描述

8、两个list根据id,筛选出某个属性值不相同的元素

// 根据id,过滤出名字和类型不相同的元素
List<Entity> updateFilter = list1.stream().filter(item ->(list2.parallelStream().anyMatch(tm->item.getId() == tm.getId()
&& (!item.getName().equals(tm.getName()) || !item.getType().equals(tm.getType())) ))).collect(Collectors.toList());

在这里插入图片描述

9、根据某个属性进行分组统计

// 根据type对元素进行分组,并统计每个type的个数
Map<String, List<Entity>> groupingBy = list2.stream().collect(Collectors.groupingBy(item -> item.getType()));
for (Map.Entry<String, List<Entity>> entry : groupingBy.entrySet()) {
    
    
    System.out.println(entry.getKey()+"的个数为:"+entry.getValue().size());
}

在这里插入图片描述

10、排序

List<Entity> descSort = descSortList(list1);

List<Entity> ascSort = ascSortList(descSort);
 
        
//根据id倒序
public List<Entity> descSortList(List<Entity> list){
    
    
    Collections.sort(list, new Comparator<Entity>() {
    
    
        @Override
        public int compare(Entity o1, Entity o2) {
    
    
            return o2.getId() - o1.getId();
        }
    });
    return list;
}

//根据id升序
public List<Entity> ascSortList(List<Entity> list){
    
    
    Collections.sort(list, new Comparator<Entity>() {
    
    
        @Override
        public int compare(Entity o1, Entity o2) {
    
    
            return o1.getId() - o2.getId();
        }
    });
    return list;
}


// 3.16排序补充
//list= list.stream().sorted(Comparator.comparing(Entity::getId)).collect(Collectors.toList());//根据id升序
list= list.stream().sorted(Comparator.comparing(Entity::getId).reversed()).collect(Collectors.toList());//根据id降序

在这里插入图片描述
在这里插入图片描述

---------------------------------- 3.16更新

11、分组求和:某个属性值相同的元素进行分组求和

//name是用户姓名,score是用户分数,根据用户姓名统计这个用户的总分数

//方法一
Map<String, Double> sum = all.stream().collect(Collectors.toMap(User::getName, User::getScore, Double::sum));

//方法二
Map<String, Double> sum1 = all.stream().collect(Collectors.groupingBy(User::getName, Collectors.collectingAndThen(Collectors.summarizingDouble(User::getScore), DoubleSummaryStatistics::getSum)));

//方法三
Map<String, Double> sum2 = all.stream().collect(Collectors.groupingBy(User::getName, Collectors.collectingAndThen(Collectors.mapping(User::getScore, Collectors.reducing(Double::sum)), Optional::get)));

以上,差不多就这些,如果还有其他的使用欢迎在评论区补充。

猜你喜欢

转载自blog.csdn.net/weixin_43165220/article/details/122077830