Java 8过滤Map对象列表,基于Map属性删除一些重复项

3

Have a

List<Map<String, Object>> allPoints = new LinkedList<>();

每个地图都包含一个名为"name"的键,其值为字符串; 需要创建一个。
 List<Map<String, Object>> expectedPoints

列表中存在重复的名称;对于这些名称,只需保留最后一个。

例如,如果列表有三个项目,并且第一项和第三项都具有值为“abc”的“name”,则生成的列表应仅包含原始列表中的第二个和第三个项目。


所以你只想要唯一的键?没有重复的? - Joey Dalu
1
不理解这个问题的任何内容。请添加更多信息并展示示例。 - Nimrod007
请提供一些你尝试做什么的例子。问题不是很清楚。 - Sneh
1
@XtremeBaumer 但是如何填充集合,以便只将最后一个重复项放入集合中。 - Adesh Kumar
2个回答

3

其中一种方法是使用辅助地图:

Map<String, Map<String, Object>> map = new LinkedHashMap<>(allPoints.size(), 0.75f, true);
allPoints.forEach(point -> map.put((String)point.get("name"), point));

List<Map<String, Object>> expectedPoints = new ArrayList<>(map.values());

这是因为Map.put方法会将新条目添加到映射表中,或覆盖现有条目的值,从而仅保留与名称关联的最后一个点。
我正在使用其重载构造函数创建一个访问有序LinkedHashMap,以保持与allPoints列表中相同的顺序。

运行良好...但是你读了OP写的最后一句话吗?我认为这个问题有点混乱。 - zlakad
ArrayList(map.values())。你漏掉了钻石操作符。 - Sneh
1
这将根据第一次看到键的顺序维护插入顺序。对于名称相同的项目1和3的示例,这将返回一个列表,其中第三个项目排在第一位。 - Sean Van Gorder
@FedericoPeraltaSchaffner LinkedHashMap 的输入参数是桶的数量,而不是元素数量 (CHM 用于元素),因此最好将其写作 allPoints.size() / 0.75 + 1 - Eugene
1
@Eugene 我知道,感谢你的反馈。但我不想让构造函数变得更加复杂。此外,由于存在重复项,地图的大小将比列表的大小要小。因此,我不希望地图被重新调整大小超过一次。 - fps

3

如果您对一个或多个键值对有限制,并且可以灵活使用Set,请编写自己的比较器并在LinkedList上使用descendingIterator,然后写入TreeSet。请参见以下代码:

        LinkedList<Map<String, Object>> allPoints = new LinkedList<>();

        Set<Map<String, Object>> expectedPoints = new TreeSet<>((objectMap1, objectMap2) ->
                objectMap2.get("name").equals(objectMap1.get("name")) ? 0 : -1
        );

        allPoints.descendingIterator().forEachRemaining(expectedPoints::add);

1
如果我用1或其他值替换-1会发生什么?虽然这是个好问题... - Adesh Kumar
项目显示的顺序将被改变。 - Vinay Prajapati

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