проблема сортировки Java - PullRequest
2 голосов
/ 19 марта 2012

У меня есть массив списков POJO, и данные в нем имеют вид

id    time
2     467
3     403
4     602
3     529
5     398

Требование состоит в том, что сначала мне нужно отсортировать данные по времени, а затем после этого должны быть одинаковые идентификаторы.один за другим, т. е.

id     time
5      398
3      403
3      529
2      467
4      602.

Изначально для сортировки по времени я использую следующую логику

Collections.sort(list, new Comparator<Asset>() {
                    @Override
                    public int compare(Asset o1, Asset o2) {

                        if (o1.getTime() > o2.getTime())

                            return -1;

                        else if (o1.getTime() < o2.getTime())

                            return 1;

                        else

                            return 0;

                    }

                });

Может ли кто-нибудь помочь мне в игре по идентификаторам на следующем этапе?

Ответы [ 3 ]

2 голосов
/ 19 марта 2012

Чтобы отсортировать данные в соответствии с приведенным вами примером, вам, вероятно, потребуется два прохода по списку.(Как иначе вы бы определили, должен ли 3 504 быть до или после 5 315?)

  1. Сортировать по времени.
  2. Сортировать список по первому индексукаждого идентификатора.

Вот пример кода:

import java.util.*;

class Asset {
    public int id;
    public int time;

    public Asset(int id, int time) {
        this.id = id;
        this.time = time;
    }

    public String toString() {
        return id + "  " + time;
    }
}


class Test {
    public static void main(String[] args) {

        List<Asset> assets = new ArrayList<Asset>();
        assets.add(new Asset(2, 467));
        assets.add(new Asset(3, 403));
        assets.add(new Asset(4, 602));
        assets.add(new Asset(3, 529));
        assets.add(new Asset(5, 398));

        // Sort according to time.
        Collections.sort(assets, new Comparator<Asset>() {
            @Override
            public int compare(Asset o1, Asset o2) {
                return new Integer(o1.time).compareTo(o2.time);
            }
        });

        // Remember the original indexes of each asset.
        final List<Asset> assetsCopy = new ArrayList<Asset>(assets);

        // Sort the collection based on the index of the first asset
        // with the same id
        Collections.sort(assets, new Comparator<Asset>() {

            private int firstIndexOf(int id) {
                for (int i = 0; i < assetsCopy.size(); i++)
                    if (assetsCopy.get(i).id == id)
                        return i;
                return -1;
            }

            @Override
            public int compare(Asset o1, Asset o2) {
                return new Integer(firstIndexOf(o1.id))
                        .compareTo(firstIndexOf(o2.id));
            }
        });


        for (Asset a : assets)
            System.out.println(a);
    }
}

Вывод:

5  398
3  403
3  529
2  467
4  602
0 голосов
/ 19 марта 2012

Поскольку Collections.sort(...) гарантированно является стабильным алгоритмом сортировки , вы можете просто выполнить сортировку по времени и затем отсортировать по идентификатору.

Стабильная сортировка гарантирует, что равные элементы останутся в том же порядке, что и раньше.

Для вашего примера:

  1. сортировка по времени
  2. сортировка по id

После первого шага все ваши времена отсортированы.После второго шага ваша коллекция сортируется по идентификатору - и для одинаковых идентификаторов они остаются в том же порядке, так как сортировка стабильна.

Так что для тех же идентификаторов они все еще отсортированы по времени во втором месте.Вы можете увеличить количество сортировок, не сохраняя состояния предыдущих сортировок.И это только потому, что вы используете стабильную сортировку.

Вывод

2  467
3  403
3  529
4  602
5  398
0 голосов
/ 19 марта 2012

ниже кода является примером. Идея состоит в том, чтобы проверить, равны ли времена, отсортированы ли они по идентификатору, иначе сортировать по времени.

Collections.sort(list, new Comparator<Asset>() {
     @Override
     public int compare(Asset o1, Asset o2) {
         if(o1.getTime() != 02.getTime()) {
             if (o1.getTime() > o2.getTime())
                 return -1;
             else
                 return 1;
         } else {
             return new Integer(o1.getId()).compareTo(o2.getId());
         }
     });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...