Как отсортировать список объектов по двум параметрам для сравнения на Java? - PullRequest
1 голос
/ 25 апреля 2011

У меня есть такой класс:

public class Zern extends Something{
 private int costA;
 private int costB;

 public int getcostA() {
     return costA;
 }

 public void setcostA(int costA) {
     this.costA = costA;
 }

 public int getcostB() {
     return costB;
 }

 public void setcostB(int costB) {
     this.costB = costB;
 }
}

У меня есть список объектов такого типа:

private List<Zern> zerns = new ArrayList<Zern>(MAX_ZERN_SIZE);

Я добавлю новые объекты в свой список, однако я всегда хочу иметь упорядоченный список в соответствии со стоимостью a, и если в списке есть объект, который имеет такую ​​же стоимость с моим объектом, который я хочу добавить, я хочу добавить, что объект в соответствии с их стоимостьюB.

Я имею в виду:

Index of objects at list   0    1    2    3    4   5
CostA                     10   15   22   22   25  36
CostB                     26   12   17   19   23  44

If I want to add an object that has a costA 22 and costB 18, 
it will locate at index 3.

Как я могу сделать это эффективно (потому что я добавлю объект в отсортированный список, чтобы это означало, что я могу использовать двоичный поиск - если это возможно, я хочу найти решение в соответствии с этим) с Comparator или что-то в этом роде?

Ответы [ 2 ]

4 голосов
/ 25 апреля 2011

Используйте Collections.sort со следующим компаратором:

Collections.sort(zerns, new Comparator<Zern>() {

    @Override
    public int compare(Zern z1, Zern z2) {
        if (z1.getcostA() == z2.getcostA()) {
            return z1.getcostB() == z2.getcostB() ? 0 : 
                z1.getcostB() < z2.getcostB() ? -1 : 1;
        } else {
            return z1.getcostA() < z2.getcostA() ? -1 : 1;
        }
    }
});

Обновление: Если вам не нужен индексированный доступ к вашим элементам, вы можете использовать реализацию отсортированного набора с первого места с пользовательским компаратором:

TreeSet<Zern> zerns = new TreeSet<Zern>(new Comparator<Zern>() {

    @Override
    public int compare(Zern z1, Zern z2) {
        if (z1.getcostA() == z2.getcostA()) {
            return z1.getcostB() == z2.getcostB() ? 0 : 
                z1.getcostB() < z2.getcostB() ? -1 : 1;
        } else {
            return z1.getcostA() < z2.getcostA() ? -1 : 1;
        }
    }
});

Теперь можно добавлять объекты, и ваш набор всегда будет сортирован (примечание: я добавил конструктор и toString в ваш класс Zern):

zerns.add(new Zern(10, 26));
System.out.println(zerns);     // => [(10,26)]
zerns.add(new Zern(22, 19));
System.out.println(zerns);     // => [(10,26), (22,19)]
zerns.add(new Zern(22, 17));
System.out.println(zerns);     // => [(10,26), (22,17), (22,19)]
zerns.add(new Zern(15, 12));
System.out.println(zerns);     // => [(10,26), (15,12), (22,17), (22,19)]

Вы можете удалить предмет

zerns.remove(new Zern(22, 17));
System.out.println(zerns);     // => [(10,26), (15,12), (22,19)]

или удалите наихудшую статью стоимости

zerns.remove(zerns.last());
System.out.println(zerns);     // => [(10,26), (15,12)]

или получите лучшую по стоимости вещь через

System.out.println(zerns.first());    // => (10,26)
1 голос
/ 25 апреля 2011

Просто сравните первые критерии. Если они совпадают, сравните второй критерий:

public int compareTo(Zern other) {
   final int result;

    if (this.costA == other.costA) {
        if (this.costB > other.costB) {
            result = 1;
        } else if (this.costB < other.costB) {
            result = -1;
        } else {
            result = 0;
        }
    } else {
        if (this.costA > other.costA) {
            result = 1;
        } else if (this.costA < other.costA) {
            result = -1;
        } else {
            result = 0;
        }
    }

    return result;
}
...