我认为add()应该忽略重复的元素,但我的输出结果中有重复项。我应该如何避免存储重复项?
我还想知道优先队列是如何检查两个元素是否重复的。我猜它使用比较器equals来比较,但我想要确保。
谢谢
我认为add()应该忽略重复的元素,但我的输出结果中有重复项。我应该如何避免存储重复项?
我还想知道优先队列是如何检查两个元素是否重复的。我猜它使用比较器equals来比较,但我想要确保。
谢谢
PriorityQueue
不对重复元素有任何限制。如果您想确保两个相同的元素从未同时存在于优先队列中,则最简单的方法是与优先队列并行维护一个单独的Set
。每次要将元素插入到优先队列中时,可以检查集合是否已包含它,如果没有,则将其添加到集合和优先队列中。每当您从优先队列中删除一个元素时,也要从集合中删除该元素。TreeSet
来替换优先队列。这样做仍然可以执行所有重要操作,并且还不允许重复。import java.util.PriorityQueue;
public class NoDuplicates<E> extends PriorityQueue<E>
{
@Override
public boolean offer(E e)
{
boolean isAdded = false;
if(!super.contains(e))
{
isAdded = super.offer(e);
}
return isAdded;
}
public static void main(String args[])
{
PriorityQueue<Integer> p = new NoDuplicates<Integer>();
p.add(10);
p.add(20);
p.add(10);
for(int i =0;i<=2;i++)
{
System.out.println(p.poll());
}
}
}
10
20
null
这表明它不会添加重复元素10
。
集合是唯一可以忽略重复项的数据结构。列表和队列不具备这个特性。(LinkedList 是一个队列)
如果你想去除重复项,可以检查你使用 take() 方法获取的条目是否与前一个相同,如果相同则忽略它。你可以按照任何方式进行比较。 ;)
hashCode()
和equals(Object obj)
以避免重复,并使用方法contains
来检查对象是否存在。class Element {
int i, j, distance;
public Element(int i, int j, int distance) {
super();
this.i = i;
this.j = j;
this.distance = distance;
}
@Override
public int hashCode() {
return Objects.hash(i, j);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Element element = (Element) obj;
return Objects.equals(i, element.i) && Objects.equals(j, element.j) ;
}
@Override
public String toString() {
return "Element [i=" + i + ", j=" + j + ", distance=" + distance + "]";
}
}
PriorityQueue<Element> pq = new PriorityQueue<>((a, b) -> (a.distance == b.distance ? a.i == b.i ? a.j - b.j : a.i - b.i : a.distance - b.distance));
pq.add(new Element(i1, j1, d1)); // element values
Element e2 = new Element(i2, j2, d2);
if(!pq.contains(e2)) {
pq.add(e2);
}