添加2个对象列表,并从最终列表中删除重复元素(除了一个字段不同)



我有一个对象类,像

class Device{
String name;
String type;
String status;
}

我有两个列表第一个是{d1,m1,active}, {d2,m2,active},{d3,m3,acticve}

第二个{d2,m2,paused},{d4,m4,paused}

我希望我的最终列表是这样的{d1,m1,active},{d2,m2,paused},{d3,m3,active},{d4,m4,paused}

我的方法是制作一个commonName{d2}列表然后将列表{d1,d2,d2,d3,d4}添加到总列表中,然后遍历总列表,如果公共deviceName(d2.contains(i.getName()))匹配,则删除状态为活动的列表(通过删除是指创建另一个列表,不添加"活动")。对象)。

除了在迭代中使用contains之外,还有其他有效的方法吗?将复杂度降低到0 (N)。

假设第一个列表中的设备具有唯一的名称,当在第二个列表中发现相同的名称时,您可以流式传输这两个列表并收集到映射合并,选择具有paused作为状态的列表。使用以下类作为示例的示例:

@ToString
@AllArgsConstructor
@Getter
static class Divice {
private String name;
private String type;
private String status;
}

和以下示例列表

List<Divice> list1 = new ArrayList<>();
list1.add(new Divice("d1", "m1", "active"));
list1.add(new Divice("d2", "m2", "active"));
list1.add(new Divice("d3", "m3", "active"));
List<Divice> list2 = new ArrayList<>();
list2.add(new Divice("d2", "m2", "paused"));
list2.add(new Divice("d4", "m4", "paused"));

then do:

List<Divice> merged = new ArrayList<>(
Stream.concat(list1.stream(),list2.stream())
.collect(Collectors.toMap(Divice::getName,
Function.identity(),
(i,j) -> "paused".equals(i.getStatus()) ? i : j,
LinkedHashMap::new)).values()
);
merged.forEach(System.out::println);

如果两个列表按名称排序,则可以执行类似合并的操作,而不需要任何包含操作。我将用python写代码,因为我有一段时间没有用java写了,如果你很难把它翻译成java就写一个注释,我会重写它:

merged = []
i = 0
j = 0
while i < len(lst1) and j < len(lst2):
if lst1[i] < lst2[j]:
merged.append(lst1[i])
i += 1
# if lst2[j] == lst1[i] you want to take the paused one (in lst2)
else: 
merged.append(lst2[j])
j += 1
# Advance i and j so there will not be duplicates
while lst1[i] == merged[-1]:
i += 1
while lst2[j] == merged[-1]:
j += 1
# Only one of these loops will run
while i < len(lst1):
merged.append(lst1[i])
i += 1
while j < len(lst2):
merged.append(lst2[j])
j += 1

我找不到一种自动化的方法让Java为你解决这个问题,所以我写了这个代码,考虑到效率。

它所做的是使用java.util.Set以便比java.util.List更快地找到元素,并实现bean对象的哈希码和等号来确定对象是否相等。

只需一次,您就可以找到重复的Item,检查其状态并在需要时覆盖它。如果在两个列表中都有活动项,则可能需要在循环中的If中再添加一次检查。

这就是产生的结果。

项{name = ' d1、类型="m1"状态="活跃"}

项{name = d2,类型="平方米",地位="暂停"}

项{name = ' d3、类型="m3"状态="活跃"}

项{name = d4, type = m4,状态="暂停"}

public class MergeList {
public static void main(String[] args) {
List<Item> list1 = new ArrayList<>();
list1.add(new Item("d1", "m1", "active"));
list1.add(new Item("d2", "m2", "active"));
list1.add(new Item("d3", "m3", "active"));
List<Item> list2 = new ArrayList<>();
list2.add(new Item("d2", "m2", "paused"));
list2.add(new Item("d4", "m4", "paused"));
Set<Item> listResult = new HashSet<>();
listResult.addAll(list1);
for(Item i : list2) {
if (listResult.contains(i) && "active".equals(i.getStatus()))
continue;
listResult.remove(i);
listResult.add(i);
}
for(Item i : listResult)
System.out.println(i);
}
}
class Item {
private String name;
private String type;
private String status;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
return name.equals(item.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
public Item(String name, String type, String status) {
this.name = name;
this.type = type;
this.status = status;
}
//getter and setters
}

最新更新