Java 项目数超过700000的频率列表(ArrayList或LinkedList)
我有一个包含Person数据类型元素的列表。找到列表中每个元素的频率的最佳方法是什么,并且减少时间消耗 我尝试过以下方法,在i7、8GB上的时间超过10分钟Java 项目数超过700000的频率列表(ArrayList或LinkedList),java,linked-list,Java,Linked List,我有一个包含Person数据类型元素的列表。找到列表中每个元素的频率的最佳方法是什么,并且减少时间消耗 我尝试过以下方法,在i7、8GB上的时间超过10分钟 ArrayList<String> frequent = new ArrayList<>(); for (Person E: myList2) { int frequency = 0; //int frequency = Collections.frequen
ArrayList<String> frequent = new ArrayList<>();
for (Person E: myList2)
{
int frequency = 0;
//int frequency = Collections.frequency(myList2, E);
for (Person e : myList2)
{
if (E.getPassName().equals(e.getPassName()))
frequency++;
}
if (frequency >= times)
frequent.add(E.getPassName());
}
ArrayList frequency=new ArrayList();
对于(个人E:myList2)
{
整数频率=0;
//int frequency=Collections.frequency(myList2,E);
对于(个人e:myList2)
{
如果(E.getPassName().equals(E.getPassName()))
频率++;
}
如果(频率>=次)
frequency.add(例如getPassName());
}
此外,即使LinkedList中存在重复项,集合的结果始终为值1。使用映射存储频率:
Map<Person, Integer> frequency = new HashMap<Person, Integer>();
for (Person person: myList2) {
if (frequency.containsKey(person)) {
frequency.put(person, frequency.get(person) + 1);
} else {
frequency.put(person, 1);
}
}
您的算法是O(n^2)
。这很糟糕。使用Collections.frequency
无法解决这一问题,它只是在传入的Collection
上循环检查是否等于。也不要用那个
在Java 8中使用映射
:
final Map<Person, Integer> count = myList2.stream()
.collect(HashMap::new, (map, i) -> {
map.merge(i, 1, Integer::sum);
}, HashMap::putAll);
Collections.frequency()
返回1,因为它将每个项目与E
进行比较,而不是将每个项目的passName
与E
的passName
进行比较?如果equals()正确,Collections.frequency应该执行您想要的操作。您可以在自己的实现中执行自定义equals。将此移动到Person.equals();那么,有什么更好的方法吗?@user3337714正如我所说:亲自重写equals()。当您执行此操作时:同时更新hashCode()@user3337714我确实会覆盖,但Collections.frequency不起作用:(frequency.contains或frequency.containskey//frequency.containsValuePerson包含各种其他数据,这将是唯一的。我只想比较Person.getPassName()@user3337714您需要覆盖equals()
和hashCode()
在您的Person
类中,基于passName
压缩对象。并使用上述相同的代码或对其进行任何更改。对不起,我是Java新手。@user3337714使用相同的代码。基本上Map
使用hashCode
和equals
方法查找bucket中的元素。我想比较Person的名称,即Person.getName()而不是person对象本身。person对象包含我不想解释的其他变量。您认为我可以实现什么?@user3337714如果两个具有相同密码的人可以被视为相等,那么按照我的建议正确地实现等于和hashCode
。否则,请使用 映射
并将Person::getPassName
而不是Person放入映射
。
final Map<Person, Integer> count = myList2.stream()
.collect(HashMap::new, (map, i) -> {
map.merge(i, 1, Integer::sum);
}, HashMap::putAll);
final Map<Person, Integer> count = new HashMap<>();
for (final Person person : myList2) {
final Integer c = count.get(person);
if (c != null) {
count.put(person, c + 1);
} else {
count.put(person, 1);
}
}
@Override
public int hashCode() {
int hash = 3;
hash = 89 * hash + Objects.hashCode(this.passName);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if (!Objects.equals(this.passName, other.passName)) {
return false;
}
return true;
}