Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите отладить Comparator 
:(
    Опции темы
zomber
Дата 11.1.2012, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 7.5.2011

Репутация: нет
Всего: нет



есть код

Код


  public enum SortOrder {
      ASC { int getModifier() { return 1; } }
    , DESC { int getModifier() { return -1; } };
    abstract int getModifier();
  }

class Test {

public ArrayList<SortOrder> order = new ArrayList<SortOrder>(Arrays.asList(SortOrder.DESC, SortOrder.ASC));
public TreeSet<ArrayList<Object>> ts = new TreeSet<ArrayList<Object>>(new ArrayListComparator(order));

public void test() {

ArrayList<Object> tmpList;

for(/* какие-то условия*/) {

 // код заполняющий tmpList

ts.add(tmpList);

}

for(ArrayList<Object> i:ts)
   System.out.println(i.toString());
      
}

}



проблема в том, что в результате формируется кривой TreeSet
а именно:
1) неправильный порядок элементов
2) дубликат, два одинаковых элемента (в сете!!!)

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

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

вручную анализировать каждый шаг очень долго, а разобраться нужно срочно

заранее благодарен за любой ответ

****

код компаратора см. ниже

Код

  class ArrayListComparator implements Comparator {
    private ArrayList<SortOrder> orderBy;
    ArrayListComparator(ArrayList<SortOrder> orderBy) {
      this.orderBy = orderBy;
    }
    ArrayListComparator() {     
    }
    public int compare( Object object1, Object object2 ) {
      int i, status = 0, modifier = 1;
      Object o1 = null, o2 = null;
              
      for(i=0; i < ((ArrayList)object1).size(); i++) {
        try {
          modifier = orderBy.get(i).getModifier();
        } catch(IndexOutOfBoundsException e) {
          System.out.println("No orderby option for column " + i);
          modifier = 1;
        } catch(NullPointerException e) {
          System.out.println("No orderby options");
          modifier = 1;
        }        
        if(i >= ((ArrayList)object2).size()) return 1*modifier;
        o1 = ((ArrayList)object1).get(i);
        o2 = ((ArrayList)object2).get(i);
        if(o1==null && !(o2==null) ) status = 1*modifier;
        if(o1.toString().equals("") && !(o2.toString().equals("")) ) status = 1*modifier;
        else status = ((Comparable)(o1)).compareTo(o2);
        if( status != 0 ) return status*modifier;                   
      }
      if(i < ((ArrayList)object2).size())
        return -1*modifier;
      return 0;
    }
  }


PM MAIL   Вверх
zomber
Дата 11.1.2012, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 7.5.2011

Репутация: нет
Всего: нет



самое обидное (хрен с ним, с порядком элементов) - как в TreeSet может вообще образоваться дубликат ???


PM MAIL   Вверх
dobrolub
Дата 11.1.2012, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 385
Регистрация: 18.12.2009
Где: Vancouver, Canada

Репутация: 11
Всего: 16



Дело в твоём компараторе. 
PM   Вверх
Dummy
Дата 12.1.2012, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 21.5.2007

Репутация: 9
Всего: 19



Цитата(zomber @  11.1.2012,  21:08 Найти цитируемый пост)
как в TreeSet может вообще образоваться дубликат ???

TreeSet, для которого указан Comparator, решает, что два элемента равны, если Comparator.compare() для этих двух объектов возвращает 0. Следовательно, в вашем коде есть какой-то баг в ArrayListComparator. Он для каких-то пар элементов, которые по смыслу являются дубликатами, возвращает ненулевое значение.

Я бы дебажил компаратор отдельно от TreeSet по следующей схеме:
  •  Создаем компаратор
  •  Создаем элементы, которые по вашим наблюдениям дублируются в TreeSet, примерно так:
Код

ArrayListComparator c = new ArrayListComparator(<тут какой-то необходимый аргумент>);

ArrayList<Object> dup1 = <элемент>; 
ArrayList<Object> dup2 = <дубликат элемента dup1>;

int comparisonResult = c.compare(dup1, dup2);
  • Убеждаемся, что (comparisionResult != 0), т. е. ошибка - в реализации ArrayListComparator.compare(). Далее дебажим пошагово ArrayListComparator.compare() и локализуем ошибку.


Это сообщение отредактировал(а) Dummy - 12.1.2012, 01:23
PM MAIL   Вверх
zomber
Дата 13.1.2012, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 7.5.2011

Репутация: нет
Всего: нет



таки сам придумал способ, удивительно что никто не подсказал
заодно он позволяет проверить, действительно ли это дубликаты или только видимость

в цикл вставляется код
Код

        for(ArrayList<Object> a: myTreeSet) {
          if( Collections.frequency(  myTreeSet, a  ) > 1 )
            System.out.println("bad element detected");
        }


PM MAIL   Вверх
priam220
Дата 13.1.2012, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 4.6.2010

Репутация: 7
Всего: 8



Мне кажется вы лечите следствие а не причину. 
Кроме того, что вы передаете листы, не совсем понятно, что Вы пытаетесь сравнивать и что служит условием равенства.

P.S. Наличие одинаковых элементов в TreeSet говорит о том, что не верно определен equals. Неправильный порядок в TreeSet - не верная логика в компараторе. 

Это сообщение отредактировал(а) priam220 - 13.1.2012, 18:19
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0450 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.