Java8 List Stream常用操作总结记录

Posted 符华-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;


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

以上是关于Java8 List Stream常用操作总结记录的主要内容,如果未能解决你的问题,请参考以下文章

Java8 Stream 流使用场景和常用操作

Java8使用Stream流实现List列表的查询统计排序分组

Java8新特性Stream流的使用

Java8新特性Stream流的使用

Java8新特性Stream流的使用

Java8新特性Stream流的使用