Java8 Streams:过滤掉一个Map

3
我是一位有用的助手,可以为您进行文本翻译。以下是您需要翻译的内容:

我正在尝试弄清如何针对以下情况使用Java8流:

假设我有以下地图:

Map<String,String[]> map = { { "01": {"H01","H02","H03"}, {"11": {"B11","B12","B13"}} };

期望的输出结果是:

map = { {"01": {"H02"}, {"11": {"B11"}};

My attempt:

map.entrySet().stream() //
        .flatMap(entry -> Arrays.stream(entry.getValue()) //
        .filter(channel -> Channel.isValid(channel))
        .collect(Collectors.toMap()));

你想一直得到第一个吗? - Eugene
请翻译以下与编程有关的内容:将翻译后的文本返回,不能是由过滤器确定的任意文本。 - Shvalb
@Shvalb 接收结果集的类型应该是 Map<String, String> 吗?还是应该像 Map<String, List<String>> 这样呢? - Ousmane D.
1
@Aominè 我会说第二个,手机上很难解决这个问题... :) 请您发布一个答案。 - Eugene
Map<String,List<String>> - Shvalb
@Eugene 尝试了,但不确定这是否是 OP 所要实现的目标 :) - Ousmane D.
2个回答

2
你当前的方法存在几个问题。
  1. 没有带有签名toMap()toMap方法,这将导致编译错误。
  2. flatMap期望一个接受类型T并返回Stream<R>的函数,而您试图传递一个映射作为返回值,因此也会导致编译错误。
相反,似乎你想要像这样的东西:
Map<String, List<String>> resultSet = map.entrySet()
                .stream() //
                .flatMap(entry -> Arrays.stream(entry.getValue())
                        .filter(Channel::isValid)
                        .map(e -> new AbstractMap.SimpleEntry<>(entry.getKey(), e)))
                .collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey,
                        Collectors.mapping(AbstractMap.SimpleEntry::getValue, 
                               Collectors.toList())));

或者更简单的解决方案:
map.entrySet()
   .stream() //
   .collect(Collectors.toMap(Map.Entry::getKey, 
               a -> Arrays.stream(a.getValue())
                          .filter(Channel::isValid)
                          .collect(Collectors.toList())));

嗯,我真的在考虑在这里将Collectors.filtering作为Collectors.groupingBy的下游收集器相关内容... - Eugene
@Eugene,但是这篇文章标记了java-8 :),尽管我现在会着手解决java-9的问题。 - Ousmane D.
@Eugene 嗯,我在考虑。不确定是否可以在这里使用 Collectors.filtering...但我们肯定可以在 valueMapper 中使用 filter - Ousmane D.
Channel::isValid?可能只需要为两个键添加一个合并函数...否则同意。 - Eugene
@Eugene 确定,我会使用方法引用,但在这种情况下,不应该有任何键冲突,因为源(一个 Map)的定义不允许重复键。 - Ousmane D.
@Eugene 好的,我明白 :) - Ousmane D.

0
这是解决你问题的另一种方式:
public static void stack2() {
    Map<String, String[]> map = new HashMap<>();
    map.put("01", new String[]{"H01", "H02", "H03"});
    map.put("11", new String[]{"B11", "B12", "B13"});

    Map<String, String[]> newMap = map.entrySet()
            .stream()
            .peek(e -> e.setValue(
                Arrays.stream(e.getValue())
                    .filter(Main::stack2Filter)
                    .toArray(String[]::new)))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

    newMap.forEach((key, value) -> 
            System.out.println("key: " + key + " value " + Arrays.toString(value)));
}

public static boolean stack2Filter(String entry) {
    return entry.equals("H02") || entry.equals("B11");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接