【问题标题】:How to filter a List which is a value of a Map entry in java 8?java - 如何过滤作为Java 8中Map条目值的List?
【发布时间】:2019-01-25 04:42:35
【问题描述】:

我有一个Map<B, List<A>>。我想根据一些依赖于 B 类型映射条目的键的谓词过滤掉一些 A。例如,这是我的数据结构:

List<Integer> list1 = Arrays.asList(5,2,3,4);
List<Integer> list2 = Arrays.asList(5,6,7,8);
List<Integer> list3 = Arrays.asList(9,10,11,12,13);
List<Integer> list4 = Arrays.asList(11,23,112);
Map<Long, List<Integer>> map = new HashMap<>();
map.putIfAbsent(2L, list1);
map.putIfAbsent(3L, list2);
map.putIfAbsent(4L, list3);
map.putIfAbsent(5L, list4);

现在我想遍历地图的 entrySet 并制作一个新地图,其中包含元素的列表,该元素是该条目的键的倍数。即输出应如下所示:

2L --> List of (2, 4)
3L --> List of (6)
4L --> List of (12)
5L --> empty List

过滤谓词使用映射条目键值来测试列表元素。如何在不修改原始地图的情况下实现这一点?

【问题讨论】:

  • StreamEx: EntryStream.of(map).flatMapValues(List::stream).filterKeyValue((k, v) -&gt; v % k == 0).grouping()

标签: java-8 collectors


【解决方案1】:

这是解决问题的一种方法,通过流式传输原始映射中的条目,并使用键和过滤列表创建一个新映射:

Map<Long, List<Integer>> newMap = map.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().stream()
                .filter(value -> value % entry.getKey() == 0)
                .collect(Collectors.toList())));

【讨论】:

    【解决方案2】:

    分两步进行可能会使其更具可读性:

        //create a new map
        Map<Long, List<Integer>> newMap = new HashMap<>();
        //add filtered entries to it
        map.entrySet().forEach(
                               e ->newMap.put( e.getKey(),e.getValue()
                                                           .stream()
                                                           .filter(value -> value % e.getKey() == 0)
                                                           .collect(Collectors.toList()))
                               );                               
    

    【讨论】:

    • 你可以在没有stream()的情况下拨打forEach()
    猜你喜欢
    • 2021-09-03
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 2018-02-18
    相关资源
    最近更新 更多