【问题标题】:Check in Map of list if exists value for specific key Java 8如果存在特定键 Java 8 的值,则检查列表的映射
【发布时间】:2018-11-15 23:37:20
【问题描述】:

在 Java 7 中我有

Map<String, List<String>> m = new HashMap<String, List<String>>();
boolean result = false;
m.put("Name1", Arrays.asList("abc*1"));
m.put("Name2", Arrays.asList("abc@*1"));


for (Map.Entry<String, List<String>> me : m.entrySet()) {
    String key = me.getKey();
    List<String> valueList = me.getValue();
    if (key.equals("Name2"){
        System.out.print("Values: ");
        for (String s : valueList) {
            if(s.contains("@"){
                result = true;
            }
        }
    }
} 

如果 Name2 包含 @ 使用任何匹配项,我如何才能得到它的布尔结果?

我尝试使用以下代码,但我不知道如何将 IT 用于特定键

result = m.values().stream().anyMatch(v -> v.contains("@"))

【问题讨论】:

  • 您的意思是if(s.contains("@"))? (双引号,不是双撇号)
  • 你有 If 代表 if''(两个撇号)而不是 "。这段代码应该是可编译的吗?

标签: java list dictionary java-8 java-stream


【解决方案1】:

怎么样

String name = "Name1";
boolean result= m.containsKey(name) && m.get(name).stream().anyMatch(a -> a.contains("@"));

【讨论】:

    【解决方案2】:

    您可以简单地使用m.get("Name2"),将(可为空的)结果放入Optional,然后使用映射:

    boolean result = Optional.ofNullable(m.get("Name2"))
        .map(l -> l.stream().anyMatch(s -> s.contains("@")))
        .orElse(false);
    

    这比遍历入口集更可取,因为HashMap.get 是 O(1),而遍历入口集是 O(n)。

    【讨论】:

    • map 应该是 .map(l -&gt; l.stream().anyMatch(s -&gt; s.contains("@")))
    • 更好:Optional.ofNullable(m.get("Name2")) .filter(l -&gt; l.stream().anyMatch(s -&gt; s.contains("@"))) .isPresent()
    【解决方案3】:

    试试这个:

    boolean result = m.entrySet().stream()
        .filter(e -> e.getKey().equals(Name2))
        .map(Map.Entry::getValue)
        .flatMap(List::stream)
        .anyMatch(s -> s.contains("@"));
    

    【讨论】:

      【解决方案4】:

      entrySet() 创建一个流,然后在anyMatch 中提供您的条件:

      result = m.entrySet()
                .stream()
                .anyMatch(v -> Objects.equals("Name2", v.getKey()) && 
                     v.getValue().stream().anyMatch(s -> s.contains("@")));
      

      或使用getOrDefault:

      result = m.getOrDefault("Name2", Collections.emptyList())
                .stream()
                .anyMatch(s -> s.contains("@"));
      

      【讨论】:

        【解决方案5】:

        执行以下操作:

        boolean result = m.getOrDefault("Name2", Collections.emptyList()).stream()
            .anyMatch(i -> i.contains("@"));
        

        如果Map 包含正确的键,请检查其作为值的List 的任何元素是否包含特定字符。如果Map 不包含密钥,则模拟空的Collection,它根本不包含任何内容,结果将自动评估为false

        编辑:正如@Michael 建议的那样,使用Collections.emptyList()new ArrayList&lt;&gt;() 更好。

        【讨论】:

        • 这是最好的方法。当大多数地图专门设计为具有 O(1) get 时,为什么要遍历所有键?
        • @Michael Java 9 提供了一个中间解决方案:Stream.ofNullable(m.get("Name2")) .flatMap(List::stream) .anyMatch(i -&gt; i.contains("@"))
        • @Holger 这完全不同,值得自己回答,你不觉得吗?
        • @Michael 这是不同的代码,但不是根本不同的逻辑,所以我不会添加仅由小代码 sn-p 组成的答案。如果您愿意,可以将其添加为您的答案的替代方案。
        • @Michael 我对所有这些答案没有异议,但我不想再添加一个。顺便说一句,我看到了根本的区别。有些答案在地图上进行线性迭代,有些答案可以避免这种情况。
        【解决方案6】:

        首先您应该按所需的键进行过滤,然后您可以使用anyMatch 来确定该键的值是否包含带有“@”字符的元素:

        result = m.entrySet ()
                  .stream ()
                  .filter (e->e.getKey ().equals (Name2))
                  .anyMatch (e->e.getValue ().stream ().anyMatch (s->s.contains ("@")));
        

        【讨论】:

          【解决方案7】:

          只需添加正确的过滤条件:

          m.entrySet()
          .stream()
          .anyMatch(entry-> entry.getKey().equals(Name2) && 
             entry.getValue()
          .stream()
          .anyMatch(string -> string.contains("@"))
          .getValue();
          

          【讨论】:

            猜你喜欢
            • 2021-05-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-05
            • 2014-06-19
            • 2015-08-06
            • 2021-03-05
            • 2020-03-11
            • 2017-11-15
            相关资源
            最近更新 更多