Сортировка Java на основе двух столбцов

Предположим, что у меня есть таблица вроде этого:

 String | Int1 | Int2
 "foo"    5      0
 "faa"    4      1
 "zaa"    0      1
 "zoo"    4      2
 "laa"    4      3
 "loo"    1      4

То, что я хотел бы получить, выглядит так:

 String | Int1 | Int2
 "foo"    5      0
 "laa"    4      3
 "zoo"    4      2
 "faa"    4      1
 "loo"    1      4
 "zaa"    0      1

Первое, что происходит, это сортировка по столбцу Int1.

Второе, что происходит, - это сортировка на основе столбца Int2, но только для строк с одинаковыми номерами в столбце Int1

Как мне подойти к этой проблеме без использования какого-либо механизма базы данных?

Ответ 1

Обычно вы делаете это с помощью List<Item>, где Item - это тип, содержащий все три значения (например, "foo", 5, 0 для первой строки).

Затем вы записали Comparator<Item>, который сравнивал значения Int1 двух объектов Item, представленных ему в compare, и если это дало определенный ответ, вернул этот ответ... и в противном случае сравнил Значения Int2.

Ответ 2

Я предполагаю, что у вас есть объект с String с 2 ints?

Самый простой способ сделать это - реализовать объект Comparable и реализовать метод compareTo(). Или вы можете передать компаратор в Collections.sort(yourListOfObjects, yourCustomComparator)

Метод compareTo() будет сравнивать первый int first и если они равны, сравните второй ints.

@Override
public int compareTo(MyObject o) {
    // compare int1s .. if equal, compare int2s and return 0,1 or -1
}

Вот полезная ссылка

http://download.oracle.com/javase/tutorial/collections/interfaces/order.html

Ответ 3

Это довольно неясно, что вы подразумеваете под столом. Но в общем случае вы сортируете данные на Java с помощью Comparator или реализуете свою структуру данных Comparable. В вашем случае вы создадите простую структуру данных, которая инкапсулирует строку в вашей таблице, а затем создайте Comparator для структуры данных строки или внесите ее Comparable.

Например

public class Row implements Comparable<Row> {
    public final String theString;
    public final int int1;
    public final int int2;

    public Row(String theString, int int1, int int2) {
        this.theString = theString;
        this.int1 = int1;
        this.int2 = int2;
   }

   public int compareTo(Row other) {
       if(this.int1 == other.int1) {
           return new Integer(this.int2).compareTo(other.int2);
       }

       return new Integer(this.int1).compareTo(other.int1);
   }
}

Затем вы должны создать List<Row> и использовать java.util.Collections.sort(List<?>) для сортировки ваших данных.

Ответ 4

Хорошо сначала определите, что вы подразумеваете под "таблицей".

Я бы обернул каждую строку в объект Row и сохранил массив этих Row s. Затем вы можете реализовать интерфейс Comparable<Row> или написать свой собственный Comparator<Row>.

Итак, либо:

...
class Row implements Comparable<Row> {
    String s;
    int int1, int2;

    ...

    public int compareTo( Row r ) {
        if( int1 != r.int1 ) return int1-r.int1;
        else return int2-r.int2;
    }
}

И вызовите Arrays.sort(rows);

Или вы можете сделать это:

Arrays.sort(rows, new Comparator<Row>() {
    public int compare( Row r1, Row r2 ) {
        if( r1.int1 != r2.int1 ) return r1.int1-r2.int1;
        else return r1.int2-r2.int2;
    }
});

где rows - Row[].

Ответ 5

Если только Java поддерживает lambdas... это тривиально на многих языках.

Но, хм, посмотрим. Вот два общих подхода (существует много разных вариантов этих тем):

  • Создайте новый тип с указанными членами
  • Сделайте реализацию типа Comparable (например, "compareTo" )
  • Поместите элементы этого нового типа в массив или список (возможно, List<NewType>)
  • Используйте Arrays.sort или Collections.sort (или аналогичные)

Или

  • Создайте вложенный массив или Список (возможно, List<List<Object>>)
  • Используйте Arrays.sort или Collections.sort (или аналогичный), используя форму, которая принимает Comparator

Счастливое кодирование.

Ответ 6

Что-то вроде этого?

public class Item implements Comparable<Item> {
    private String s;
    private Integer int1;
    private Integer int2;

    @Override
    public int compareTo(Item o) {
        int compare = int1.compareTo(o.int1);
        return compare != 0 ? compare : int2.compareTo(o.int2);
    }
}

Ответ 7

Я бы использовал CompareToBuilder внутри реализации Comparator.

Пример использования,

    new Comparator<YourObjectType>() {
            @Override
            public int compare(YourObjectType o1, YourObjectType o2) {
                return new CompareToBuilder()
                   .append(o1.firstFieldToCompare, o2.firstFieldToCompare)
                   .append(o1.secondFieldToCompare, o2.secondFieldToCompare)
                   .toComparison();
            }
        }