我有一个包含重复对象的列表,只是时间戳不同,我需要获取最新的时间戳值。
我正在添加一些与案例类似的模拟数据
List<Person> personList = new ArrayList<>();
personList.add( new Person( name1,created, 1563428880 ));
personList.add( new Person( name2,created, 1563428880 ));
personList.add( new Person( name3,created, 1563428880 ));
personList.add( new Person( name2,updated, 1563429998 ));
personList.add( new Person( name3,updated, 1563429998 ));
我有以下代码来从列表中获取唯一对象
for (Person person: personList) {
if(uniqueLatestPersonMap.containsKey( person.getName() )) {
Person availablePerson = uniqueLatestPersonMap.get(person.getName());
int status = availablePerson.getTimestamp().compareTo(person.getTimestamp());
if(status == -1) {
uniqueLatestPersonMap.put(person.getName(),person);
}
} else {
uniqueLatestPersonMap.put(person.getName(),person);
}
}
由于我的大量数据和响应时间不如我们预期。有什么方法可以改善响应时间,也可以通过其他方法有效地做到这一点。
我的输出列表将具有
Person( name1,created, 1563428880 )
Person( name2,updated, 1563429998 );
Person( name3,updated, 1563429998 );
先谢谢大家。
答案 0 :(得分:0)
您可以按名称对阵列列表进行排序,然后处理数据并检查性能。
答案 1 :(得分:0)
您可以将Java的TreeMap用于uniqueLatestPersonMap。当搜索uniqueLatestPersonMap.containsKey(person.getName())以获取现有名称时,这将限制比较的次数。
答案 2 :(得分:0)
请使用您的唯一属性覆盖equals
和hashCode
; timeStamp
。
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return getTimeStamp() == person.getTimeStamp();
}
@Override
public int hashCode() {
return Objects.hash(getTimeStamp());
}
及其后的Java8
代码将从列表中获取唯一记录。
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("person1", 1563428880));
personList.add(new Person("person2", 1563428881));
personList.add(new Person("person3", 1563428883));
personList.add(new Person("person4", 1563428880));
Collection<Person> uniquePersonList = getUniquePersonList(personList);
uniquePersonList.forEach(System.out::println);
}
private static Collection<Person> getUniquePersonList(List<Person> personList) {
return personList.stream()
.collect(Collectors.toMap(Person::getTimeStamp, Function.identity(), (person1, person2) -> person1))
.values();
}
因此,将输出以下内容。
Person{name='person1', timeStamp=1563428880}
Person{name='person2', timeStamp=1563428881}
Person{name='person3', timeStamp=1563428883}
注意:为简洁起见,省略了一些显而易见的代码(getter,setter,attributes和toString()
)。
答案 3 :(得分:0)
您可以使用Java Stream API。
我尝试使用5M,大约花了10秒钟。 (我只有3个不同的名字,所以我认为这对表演有帮助。)
这是我的代码:
public static void main(String []args){
List<Person> personList = new ArrayList<>();
for(int i = 0; i < 5_000_000; i++) {
personList.add(new Person("name1", 1563428880 +i));
personList.add(new Person("name2", 1563428880+i));
personList.add(new Person("name3", 1563428880+i));
personList.add(new Person("name2", 1563429998+i));
personList.add(new Person("name3", 1563429998+i));
}
System.out.println("starting ..");
long time = System.currentTimeMillis();
// Groups persons by name
Map<String, List<Person>> m = personList.parallelStream()
.collect(Collectors.groupingBy(Person::getName));
// For each name, get the person with the highest timestamp
List<Person> p = m.entrySet().stream()
.map(e -> e.getValue().parallelStream().max(Comparator.comparingInt(Person::getTime)))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
System.out.println("done in " + (System.currentTimeMillis() - time) + "ms.");
System.out.println(p);
}
starting .. done in 8874ms. [name3-1568429997, name2-1568429997, name1-1568428879]