我试图找到最快和最有效的方法来获得基于自定义可比较实现的对象arrayList中的前K个项。
在我的研究过程中,有人建议我应该使用最大/最小堆,它在java中被抽象为优先级队列。2然而,问题是我不知道如何在对象的数组列表上实现它
下面是我对象示例
public class PropertyRecord {
private long id;
private String address, firstName, lastName, email, ownerAddress;
private LocalDate dateSold;
private BigDecimal price;
public PropertyRecord(long id, String address, String firstName, String lastName, String email, String ownerAddress, LocalDate dateSold, BigDecimal price) {
this.id = id;
this.address = address;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.ownerAddress = ownerAddress;
this.dateSold = dateSold;
this.price = price;
}
//getters and setters...
}
我想根据价格得到前k个项目。我写了一个方法(见下文),它接受arrayList和K(得到前K个项目),并使用StreamAPI,但我知道这不是最有效的方法,因为这将排序整个列表,即使我只想得到前K个项目。所以我想有O(k log n)而不是O(n)。
//return the top n properties based on sale price.
public List<PropertyRecord> getTopProperties(List<PropertyRecord> properties, int n){
//using StreamAPI
return properties.stream()
.sorted((p1, p2) -> p2.getPrice().compareTo(p1.getPrice()))
.limit(n)
.collect(Collectors.toList());
}
有没有人帮忙?
2条答案
按热度按时间5cg8jx4n1#
Guava包含了一个TopKSelector类,它可以做到这一点。
在最新的Guava版本中,此功能现在公开为
Comparators.greatest()
。然而,如果您不局限于使用
ArrayList
进行存储,那么使用PriorityQueue
可能会更好,因为它自然会按照优先级顺序保存元素。cbjzeqam2#
在java中有几种可能的方法来计算top K,那么哪种方法最有效呢?让我们试试:
我尝试了以下
inputListSize
和topK
组合:以下是基准测试结果:
使用Spot Profiler for Java and Kotlin:
Collections.sort
获胜。:)