Java сортировка по двум столбцам - PullRequest
10 голосов
/ 29 июля 2011

Допустим, у меня есть такая таблица:

 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

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

Ответы [ 7 ]

10 голосов
/ 29 июля 2011

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

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

4 голосов
/ 29 июля 2011

Довольно непонятно, что вы подразумеваете под таблицей.Но в общем случае вы сортируете данные в 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 голосов
/ 29 июля 2011

Я предполагаю, что у вас есть объект со строкой с 2-мя целыми числами?

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

Метод compareTo () сравнивает первое int первым, а если они равны, сравнивает вторые целые.

@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 голосов
/ 29 июля 2011

Ну, сначала определим, что вы подразумеваете под «таблицей».

Я бы обернул каждую строку в объекте 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[].

2 голосов
/ 29 июля 2011

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

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

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

Или

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

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

1 голос
/ 29 июля 2011

Как то так?

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);
    }
}
0 голосов
/ 04 июля 2016

Я бы использовал 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();
            }
        }
...