PriorityQueue的副本,不干扰原始PriorityQueue

时间:2014-10-09 14:42:44

标签: java copy priority-queue

我正在尝试复制PriorityQueue对象。

我的目标是在不修改原始PriorityQueue

的情况下更改我的副本的某些对象

为了做到这一点,我做了我的PriorityQueue的副本,并删除了我的副本的值,但是当我检查我的PriorityQueue是否相同时,遗憾的是原始的PriorityQueue也被更改了......如果你有任何建议都会受到欢迎。

请找一个我试过的例子:

public class PQExample
{
    public int id;
    public int price;
    public String name;
    public long date;

        public PQExample(int id, int price, String name, long time)
        {
            this.id = id;
            this.price = price;
            this.name = name;
            this.date = time;
        }

        public static void main(String[] args)
        {
            PriorityQueueComparator pqc = new PriorityQueueComparator();
            PriorityQueue<PQExample> PQ = new PriorityQueue<PQExample>(pqc);
            int setID = 1000;
            int setDate = 0;
            PQ.add(new PQExample(setID++, 24 , "Mat", setDate++));
            PQ.add(new PQExample(setID++, 25 , "Tommy", setDate++));
            PQ.add(new PQExample(setID++, 22 , "Kate", setDate++));
            PQ.add(new PQExample(setID++, 26 , "Mary", setDate++));
            PQ.add(new PQExample(setID++, 24 , "Ronny", setDate++));
            PQExample valueToDel = new PQExample(1000,22,"Mat",0);

            PriorityQueue<PQExample> PQCopy = new PriorityQueue<PQExample>();
            PQCopy = PQ;

            //Now I want to delete only in PQCopy and not in PQ    
            PQCopy.remove(valueToDel);

            //Unfortunately Mat was deleted of both objects : PQ and PQCopy...
            for (int i = 0; i < 4; i++) {
                System.out.println("Queue in: " + i + " is " + PQ.peek().name + " with the price of " + PQ.peek().price);
                PQ.poll();
            }
        }
@Override
public boolean equals(Object o)
{
    if (o instanceof PQExample)
    {
        PQExample pqExample = (PQExample)o;
        return id == pqExample.id;
    }
    return false;
}


class PriorityQueueComparator implements Comparator<PQExample>
{
    @Override
    public int compare(PQExample o1, PQExample o2) {
        if (o1.price < o2.price){return 1;}else if (o1.price > o2.price){return -1;}
        else
        {if (o1.date<o2.date){return -1;}else{return 1;}}
    }
}

2 个答案:

答案 0 :(得分:2)

你在这做什么:

PriorityQueue<PQExample> PQCopy = new PriorityQueue<PQExample>();
PQCopy = PQ;

时:

  1. 创建一个新对象并将其引用存储在PQCopy
  2. PQCopy引用与PQ
  3. 相同的对象

    您需要使用复制构造函数创建一个新的PriorityQueue对象:

    PriorityQueue<PQExample> PQCopy = new PriorityQueue<>(PQ);
    

    当您阅读here时:

      

    创建包含指定元素的PriorityQueue   集...

    但请注意,虽然它将集合复制到新集合中,但引用的对象是相同的。这意味着如果更改包含的对象属性,则会在两个集合的元素中注意到此更改。

    修改

        PriorityQueue<Integer> PQ= new PriorityQueue<Integer>();
        PQ.add(3);
        PQ.add(4);
        PriorityQueue<Integer> PQCopy = new PriorityQueue<>(PQ);
        PQCopy.remove();
    
        for(Integer i: PQ)
        {
            System.out.println(i);
        }
    
        for(Integer i: PQCopy)
        {
            System.out.println(i);
        }
    

    另一个示例显示了如果包含的对象是可变的,对它们的更改也会影响复制的列表:

       class CTest implements Comparable<CTest> {
            public CTest(int v) {
                this.v = v;
            }
            Integer v;
    
            @Override
            public int compareTo(CTest o) {
                return this.v.compareTo(o.v);
            }
        }
    
        PriorityQueue<CTest> PQ= new PriorityQueue<CTest>();
        PQ.add(new CTest(3));
        PQ.add(new CTest(4));
        PriorityQueue<CTest> PQCopy = new PriorityQueue<>(PQ);
        PQCopy.iterator().next().v = new Integer(6);
    
        for(CTest i: PQ)
        {
            System.out.println(i.v);
        }
    
        for(CTest i: PQCopy)
        {
            System.out.println(i.v);
        }
    

答案 1 :(得分:2)

PQcopy只是对实际PriorityQueue对象的第二次引用。您希望clone原始PQ而不是仅指定参考。 PriorityQueue has a constructor为你做这件事:

PriorityQueue<PQExample> PQCopy = new PriorityQueue<PQExample>(PQ)

顺便说一下,你应该遵循Java的大小写约定 - 用大写字母起始变量名是不受欢迎的。