仅当集合不包含具有一个匹配属性的对象时,才将对象X添加到集合中

时间:2019-03-02 00:28:59

标签: java collections java-stream

我刚刚开始弄乱Java流,并编写了如下内容:

List<Device> devicesToDelete = new ArrayList<>();
List<Device> oldDeviceList = getCurrentDevices();

for (Device deviceFromOldList : oldDeviceList)
{
    // part to simplify

    boolean deviceNotExistOnDeleteList =
        devicesToDelete.stream().noneMatch(nd -> nd.id == deviceFromOldList.id);

    if (deviceNotExistOnDeleteList) {
        devicesToDelete.add(deviceFromOldList);
    }

    // part to simplify end
}

可以进一步简化吗?

我没有使用Set,因为我的Device.equals()实现比较了该类中的所有字段。在这里,我只需要比较id字段。

1 个答案:

答案 0 :(得分:0)

Just use a Map

Map<Object, Device> devicesToDelete = new HashMap<>();
List<Device> oldDeviceList = getCurrentDevices();

for(Device deviceFromOldList: oldDeviceList) {
    devicesToDelete.putIfAbsent(deviceFromOldList.id, deviceFromOldList);
}

// in case you need a Collection:
Collection<Device> allDevicesToDelete = devicesToDelete.values();

putIfAbsent will only store the mapping if the key is not already present. This will get you the performance of hashing while only considering the ID.

You may change the type argument Object in Map<Object,Device> to whatever type your ID has, though it doesn’t matter for the operation, if all you need at the end, is the Collection<Device>.

You can use a Stream, e.g.

Map<Object, Device> devicesToDelete = getCurrentDevices().stream()
    .collect(Collectors.toMap(
        deviceFromOldList -> deviceFromOldList.id, Function.identity(), (a,b) -> a));

though, it’s debatable whether this is a necessary change. The loop is not bad.