繁体   English   中英

如何通过Java 8 Lambda在列表中使用地图过滤器

[英]How to use Map filter in list by Java 8 lambda

Map是Map<String, List<User>>并且List是List<User> 我想用

Map<String,List<User>> newMap = oldMap.stream()
.filter(u ->userList.stream()
.filter(ul ->ul.getName().equalsIgnoreCase(u.getKey()).count()>0))
.collect(Collectors.toMap(u.getKey, u.getVaule()));

无法更改为新的Map 为什么?

也许您打算创建输入Map的条目Set的Stream。

Map<String,List<User>> newMap =
    oldMap.entrySet().stream()
          .filter(u ->userList.stream().filter(ul ->ul.getName().equalsIgnoreCase(u.getKey())).count()>0)
          .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

这将创建一个Map ,保留原始Map的条目,这些条目的键等于userList成员中至少一个成员的名称(忽略大小写)。

您的代码有几个问题:

  • Map没有stream() :它的条目集有,所以您需要先调用entrySet()
  • 有两个放错了括号的地方
  • Collectors.toMap代码不正确:您需要使用lambda u -> u.getKey() (或方法引用Map.Entry::getKey ),而不仅仅是表达式u.getKey() 另外,您拼写了getValue()

这将是一个更正的代码:

Map<String, List<User>> newMap = 
        oldMap.entrySet()
              .stream()
              .filter(u -> userList.stream()
                                   .filter(ul ->ul.getName().equalsIgnoreCase(u.getKey())).count() > 0             
              ).collect(Collectors.toMap(u -> u.getKey(), u -> u.getValue()));

但是这里有几点注意事项:

  • 您仅在过滤以查看计数是否大于0:而是可以使用anyMatch(predicate) 这是一个简短的终端操作,如果谓词对于Stream中的至少一个元素为true ,则返回true 这还有一个优点,即此操作可能不会处理Stream中的所有元素(过滤时会处理)
  • 这是低效的,因为每次需要过滤Stream元素时都要遍历userList 最好使用具有O(1)查找的Set (因此,首先将userList转换为userSet ,将用户名转换为小写,然后在该set中搜索小写值的用户名)。 。

这将是一个性能更高的代码:

Set<String> userNameSet = userList.stream().map(u -> u.getName().toLowerCase(Locale.ROOT)).collect(toSet());
Map<String,List<User>> newMap = 
        oldMap.entrySet()
              .stream()
              .filter(u -> userNameSet.contains(u.getKey().toLowerCase(Locale.ROOT)))
              .collect(Collectors.toMap(u -> u.getKey(), u -> u.getValue()));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM