Java 基于对象的属性从包含对象的列表中删除重复项
所以我有一个对象的Arraylist,这些对象有名称和时间戳作为属性。我需要一种方法,当它在Arraylist中找到重复的名称时,它会用较小的timpestamp删除该对象。理论上看起来很容易,但我真的被卡住了。我尝试的是:Java 基于对象的属性从包含对象的列表中删除重复项,java,arraylist,duplicates,attributes,remove,Java,Arraylist,Duplicates,Attributes,Remove,所以我有一个对象的Arraylist,这些对象有名称和时间戳作为属性。我需要一种方法,当它在Arraylist中找到重复的名称时,它会用较小的timpestamp删除该对象。理论上看起来很容易,但我真的被卡住了。我尝试的是: for (int j=0; j<travellers.size(); j++){ if ( (travellers.get(i).getName() ).equals( sorted_travellers.get
for (int j=0; j<travellers.size(); j++){
if ( (travellers.get(i).getName() ).equals( sorted_travellers.get(j).getName() ) ){
if (travellers.get(i).getTimestamp() < sorted_travellers.get(j).getTimestamp()){
sorted_travellers.remove(j);
}else if (travellers.get(i).getTimestamp() > sorted_travellers.get(j).getTimestamp()){
sorted_travellers.remove(i);
}
}
}
}
for(int j=0;j.get(j.getTimestamp()){
移除(i);
}
}
}
}
如果您不介意使用StreamEx,则可以轻松完成:
StreamEx.of(travelers)
.sorted(Comparator.comparing(Traveler::getName))
.collapse((t1,t2) -> t1.getName().equals(t2.getName()),
(t1,t2) -> {
if(t1.getTimestamp().compareTo(t2.getTimestamp()) > 0){
return t1;
}
return t2;
}).toList();
另一个不分配任何额外内存且具有n*lgn时间复杂度的解决方案可能是:
travelers.sort(Comparator.comparing(Traveler::getName)
.thenComparing(Traveler::getTimestamp).reversed()
);
//Now list sorted in order when all items with the same name are near and highest timestamp is first
Iterator<Traveler> iterator = travelers.iterator();
Traveler current = null;
Traveler next = null;
while (iterator.hasNext()) {
if (current == null) {
current = iterator.next();
} else {
next = iterator.next();
if (next.getName().equals(current.getName())) {
iterator.remove();
} else {
current = next;
}
}
}
travelers.sort(Comparator.comparing(Traveler::getName)
.thenComparing(Traveler::getTimestamp).reversed()
);
//现在,当具有相同名称的所有项目都接近并且最高时间戳位于第一位时,列表按顺序排序
迭代器迭代器=travelers.Iterator();
出行者电流=零;
Traveler-next=null;
while(iterator.hasNext()){
如果(当前==null){
current=iterator.next();
}否则{
next=迭代器.next();
if(next.getName().equals(current.getName())){
iterator.remove();
}否则{
当前=下一个;
}
}
}
要删除重复项并仅保留具有最新时间戳的记录,您可以这样做:
List travelers=。。。
//确定要保留的Traveler对象。
Map byName=newhashmap();
适用于(旅行者:旅行者){
byName.merge(Traveler.getName(),Traveler,
(a,b)->a.getTimestamp()>b.getTimestamp()?a:b);
}
//移除不应保留的旅行者物品。
//使用迭代器防止ConcurrentModificationException。
for(Iterator iter=travelers.Iterator();iter.hasNext();){
Traveler Traveler=iter.next();
if(traveler!=byName.get(traveler.getName())
iter.remove();
}
您可以尝试以下方法:
List<Traveller> travellers = new ArrayList<>();
travellers.add(new Traveller("test", 0L));
travellers.add(new Traveller("test", 1L));
Map<String, Traveller> latestTravellers = new HashMap<>();
for (var traveller : travellers) {
latestTravellers.merge(traveller.getName(), traveller,
(existing, incoming) -> incoming.getTimestamp() > existing.getTimestamp() ? incoming : existing);
}
Collection<Traveller> updatedTravellers = latestTravellers.values();
List travelers=new ArrayList();
旅行者。添加(新旅行者(“测试”,0L));
旅行者。添加(新旅行者(“测试”,1L));
Map latesttravelers=newhashmap();
适用于(var旅行者:旅行者){
LatestTravelers.merge(traveler.getName(),Traveler,
(现有,传入)->传入.getTimestamp()>现有.getTimestamp()?传入:现有);
}
Collection UpdatedTravelers=LatestTravelers.values();
公共静态列表过滤器(列表旅行者){
找到的列表=新的ArrayList();
return travelers.stream()
.排序((t1,t2)->-t1.时间戳.比较(t2.时间戳))
.filter(t->!已找到.contains(t.name))
.peek(t->found.add(t.name))
.collect(Collectors.toList());
}
public static List<Traveler> filter(List<Traveler> travelers) {
List<String> found = new ArrayList<>();
return travelers.stream()
.sorted((t1, t2) -> -t1.timestamp.compareTo(t2.timestamp))
.filter(t -> !found.contains(t.name))
.peek(t -> found.add(t.name))
.collect(Collectors.toList());
}