通过流java 8在地图中折叠两个列表

Posted

技术标签:

【中文标题】通过流java 8在地图中折叠两个列表【英文标题】:fold two list in map by stream java 8 【发布时间】:2022-01-22 04:52:09 【问题描述】:

我想摆脱返回映射的流操作中的方法和折叠列表,我该怎么做?

enum Type 
 type1, type2


public List<String> getList(Type type)
  return Arrays.stream(values())
           .filter(some->condition)
           .filter(var -> var.equals(type))
           .sorted()
           .collect(Collectors.toList());
 

// I want to move this logic into stream which is above it
public Map<Type,List<String>> getResultMap()
 Map<Type,List<String>> map = new HashMap<>();

    map.put(type1, getList(type1);
    map.put(type2, getList(type2);
 
    return map;

我期望返回地图的方法收集了两个带有两个键的列表:

public Map<Type,List<String>> getResultMap()
 return             // do here logic from getList + getResultMap
               
         .collect(Collectors.toMap);


【问题讨论】:

你能说得更清楚一些吗? 你从哪里得到type1type2 @magicmn 它的枚举有两个条目 使用 Enum.values() 获取所有枚举,然后将它们收集到地图中? Arrays.stream(YourEnum.values()).collect(Collectors.toMap(Function.identity(), v -&gt; getList(v)))。我认为删除 getList 不会使您的代码更具可读性,因此它可能应该保留。 您没有提供足够的信息来提供最佳解决方案。您应该发布您的列表和预期输出的示例。 【参考方案1】:

不清楚你到底想要什么,所以我提出以下建议。

enum Type 
    TYPE1, TYPE2 // enum constants are usually upper case by convention

    

static class SomeClass 
    Type type;
    String someValue;
    
    public SomeClass(Type type, String value) 
        this.type = type;
        this.someValue = value;
    
    
    public String getValue() 
        return someValue;
    
    
    public Type getType() 
        return type;
    
    
    public String toString() 
        return String.format("%s, %s", type, someValue);
    

这是SomeClass 的任意列表,其中每个实例可以包含TYPE1TYPE2

List<SomeClass> list = List.of(
        new SomeClass(Type.TYPE1, "A"),
        new SomeClass(Type.TYPE2, "B"),
        new SomeClass(Type.TYPE2, "C"),
        new SomeClass(Type.TYPE2, "D"),
        new SomeClass(Type.TYPE1, "E"),
        new SomeClass(Type.TYPE1, "F"),
        new SomeClass(Type.TYPE1, "G"));

现在只需使用groupingBy() 收集器流式传输列表创建按类型键控的映射。

    
Map<Type, List<SomeClass>> map = list.stream()
        .collect(Collectors.groupingBy(SomeClass::getType));

map.entrySet().forEach(System.out::println);

打印

TYPE2=[TYPE2, B, TYPE2, C, TYPE2, D]
TYPE1=[TYPE1, A, TYPE1, E, TYPE1, F, TYPE1, G]

如果您只想要地图中类的特定值,那么您可以这样做。第二个收集器,将类映射到您想要的特定类型(在本例中为 getValue() 返回的字符串)。

Map<Type, List<String>> map = list.stream()
        .collect(Collectors.groupingBy(SomeClass::getType,
                Collectors.mapping(SomeClass::getValue,
                        Collectors.toList())));

map.entrySet().forEach(System.out::println);

打印

TYPE1=[A, E, F, G]
TYPE2=[B, C, D]

【讨论】:

如果您提供更多信息,我可以根据需要进行调整。【参考方案2】:

让我们试试这段代码。

// List<String> list
List<String> list = Arrays.asList("A", "B", "C");
// Stream of Type, using object here as example
Map<Object, String> map = Stream.of("Type A", "Type B", "Type C").collect(
        Collectors.toMap(type -> type, type ->  
            // getList filter or some other logics
            return list.stream().filter(y -> type.contains(y)).findFirst().orElse(null); 
));

【讨论】:

以上是关于通过流java 8在地图中折叠两个列表的主要内容,如果未能解决你的问题,请参考以下文章

如何使用流将列表转换为带有索引的地图 - Java 8?

Java 8 流:列表到按 [重复] 分组的平面地图

Java 8 流:迭代列表映射

将对象列表转换为映射Java 8流

使用Java 8模式匹配将地图转换为列表

如何在 Java 8 中展平地图内的列表