Элементы ранжирования в TreeSet - PullRequest
2 голосов
/ 20 ноября 2010

Я знаю, что в наборе деревьев Java не может быть идентичных элементов, и поэтому мне нужно как-то отличать один элемент от другого, даже если они имеют одинаковое «значение».Я хочу иметь возможность ранжировать элементы, и я замечаю интересное поведение.

TreeSet<Integer> set = new TreeSet<Integer>(new Comparator<Integer>()
        {
            public int compare(Integer arg0, Integer arg1) 
            {
                if(arg0 > arg1)
                    return -1;
                return 1;
            }
        });

        set.add(40);
            set.add(20);
        set.add(30);
            set.add(20);

        for(Integer i:set)
        {
            System.out.println("Rank: "+(set.headSet(i,false).size()+1)+" Number: "+i);
        } 

И это вывод:

Rank: 1 Number: 40
Rank: 3 Number: 30
Rank: 5 Number: 20
Rank: 5 Number: 20

Это то, что должна делать гарнитура:

Returns a view of the portion of this set whose elements are less than (or equal to, if inclusive is true) toElement. The returned set is backed by this set, so changes in the returned set are reflected in this set, and vice-versa. The returned set supports all optional set operations that this set supports. 

Я сортирую в порядке убывания, поэтому я думаю, что должно быть наоборот.Первый элемент не имеет ничего больше, чем он, поэтому он возвращает 0, а затем я добавляю 1, чтобы получить его ранг.Второй элемент имеет одну вещь больше, чем он, поэтому я думаю, что он должен возвращать 1, добавив 1, делает 2. Это немного странно.Я думаю, что делаю простую ошибку.Мне также нужно выяснить, как бороться с двумя 20-х годов.Я хочу, чтобы их ранг был 3, но древовидная структура считает, что они разные числа.Я полагаю, я мог бы использовать TreeMultiSet или какую-либо другую стороннюю библиотеку.

Ответы [ 2 ]

2 голосов
/ 20 ноября 2010

Два 20 являются проблемой, потому что ваша реализация сравнения нарушает контракт :

Разработчик должен обеспечить sgn (x.compareTo (y)) == -sgn(y.compareTo (x)) для всех x и y.

, если x = 20 и y = 20, это не так в вашей реализации: 1 == - (1)

Вы можете решить эту проблему, возвращая 0, если arg0.equals (arg1).

Примечание: вам нужно использовать «равно» вместо «==» для объектов класса Integer.

0 голосов
/ 20 ноября 2010

Полагаю, я мог бы использовать TreeMultiSet или другую стороннюю библиотеку.

Поскольку вы нарушаете одну из основных характеристик набора, я бы сказал, что вы не должны использовать Set или TreeSet, по крайней мере, напрямую. Опции:

  • используйте List (и сохраняйте его отсортированным с Collections.sort () и Collections.binarySearch ())
  • используйте IdentityHashMap и просто используйте значение в качестве ключа, сопоставленного с ним
  • используйте TreeMap и сопоставьте значение с числом случаев (извлечение в список и сортировка при необходимости)
  • использовать стороннюю библиотеку (Bag или MultiSet)
  • реализовать собственную сумку / мультисеть

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

...