2015-01-26 6 views
1

Итак, я не знаю, есть ли элегантное решение, но здесь. Я хочу отсортировать список, но список содержит три типа элементов. Я хочу, чтобы тип A был отсортирован в алфавитном порядке, тип B & C будет внизу и отсортирован в алфавитном порядке (тип B & C будет объединен).Сортировка списка на основе двух условий

Вот мой код:

public int compareTo(Friendship another) { 
    if(this.getType().equals(TypeA) && 
      another.getType().equals(TypeA)){ //if they are both type A, just sort based on user name 

     return this.getUsername().compareTo(
       another.getUsername()); 
    } 
    else if(this.getType.equals(TypeA)){ 
     return -1; 
    } 
    else if(another.getType().equals(TypeA)){ 
     return 1; 
    } 
    else{ //this will be hit if they are either Type B or C, then just sort based on username 
     return this.getUsername().compareTo(
       another.getUsername()); 
    } 
} 

EDIT: извините, я должен был объяснить это намного лучше. Проблема в том, что приведенный выше код не работает. Из того, что я вижу, список, похоже, не упорядочен должным образом. Список TypeA по какой-то причине упорядочен напротив того, что я хочу (Z -> A). И список TypeB & C сортируется только наполовину. Поэтому я предполагаю, что в моем коде есть ошибка. Дайте мне знать, если вам нужно больше информации .

EDIT2: Еще несколько тестов на выборках, и похоже, что строки не сортируются вообще. Я сделал как

this.getUsername().compareTo(
      another.getUsername()); 

и

another.getUsername().compareTo(
      this.getUsername()); 

EDIT 3: вы, ребята, были правы. была ошибка в другом месте моего кода (это было несвязано). Извините ... также не знаю, что делать в этом случае. Кому я даю правильный ответ?

+0

Ваша сортировка по алфавиту не будет работать так, как вы указали. String.compareTo (String) использует лексикографическое упорядочение. Возможно, вам придется добавить некоторые соображения для чувствительности к регистру. Извините, если это немного упрощает просмотр. –

+0

@ StephenSouness Я не думаю, что это должно иметь большое значение. он должен просто отсортировать его точно как строки обычно сортируются – Sree

+0

Хорошо. Трудно сказать, не имея никакого контекста, но если вы счастливы, что Зебра покажет перед aardvark (например), тогда это ваше решение. –

ответ

2

Если я ты, я не изменю структуру, но только оптимизировать эти немного

public int compareTo(Friendship another) { 


     if(!this.getType().equals(another.getType()){ 
     //if type are not equal, so we might have at most one A 

      if(this.getType.equals(TypeA)){ //on left side 
      return -1; 
      } 

      if(another.getType().equals(TypeA)){ //or, on rightside 
      return 1; 
      } 
     } 
      //or we have on both sides or neither side 
      return this.getUsername().compareTo(
        another.getUsername()); 
     } 
+0

@sree, если вы хотите, чтобы заказ на реванш выполнял 'another.getUsername(). CompareTo (this.getUsername()). Можете ли вы также предоставить некоторые примеры данных. – user902383

+0

Я сделал то, что вы предложили, и собрал больше данных. Пожалуйста, см. Мое редактирование, похоже, что строки не сортируются вообще. – Sree

+0

@Sree вы можете предоставить некоторый ввод и вывод, потому что для меня он работает отлично http://ideone.com/5BsqqJ – user902383

1

Я использую аналогичное решение в той же ситуации, и я думаю, что это хорошо.

Но код может быть короче:

public int compareTo(Friendship another) { 
    boolean thisOnTop = getType().equals(TypeA); 
    boolean anotherOnTop = another.getType().equals(TypeA); 
    if (thisOnTop != anotherOnTop) { 
     return thisOnTop ? -1 : 1; 
    } else { 
     return this.getUsername().compareTo(another.getUsername()); 
    } 
} 
+0

Мне нравится, как просто ваш код. Но, пожалуйста, см. Мое редактирование. Мне жаль, что я должен был объяснить себя лучше. Вам также пришлось сортировать список с двумя разными условиями в вашей программе? – Sree

+0

@ Да, да, это работает. Вероятно, 'getType(). Equals (TypeA)' не работает так, как вы ожидали. Также 'getUsername()' регулярная строка (или сложный объект, который реализует Comparable)? – fRoStBiT

+0

TypeA - это просто перечисление, а имя пользователя - это просто строка – Sree

1

Вы просто должны реализовать СотрагеТо в 3 класса с этой логикой вы сказали. Что-то вроде этого:

// TypeA.class 
// TypeA class will have priority over the other two, so just sort by whatever you want 
public int compareTo(AnotherType anotherType) { 
    if (this.equals(anotherType)) // TypeA vs TypeA - alphabetically 
     return this.getUsername().compareTo(anotherType.getUsername()); 
    else // otherwise typeA is greater 
     return 1; // 1 means greater than 
} 

// TypeB.class 
public int compareTo(AnotherType anotherType) { 
    if (this.equals(anotherType)) // both typeB, sort alphabetically 
     return this.getUsername().compareTo(anotherType.getUsername()); 
    else 
     if(this.equals(typeC)) // TypeB vs TypeC, alphabetically 
      return this.getUsername().compareTo(typeC.getUsername()); 
     else // TypeB vs TypeA 
      return -1; // -1 means lesser than 
} 

//TypeC.class 
public int compareTo(AnotherType anotherType) { 
    if (this.equals(anotherType)) // TypeC vs TypeC - alphabetically 
     return this.getUsername().compareTo(anotherType.getUsername()); 
    else 
    if(this.equals(typeB)) // TypeC vs TypeB - alphabetically 
     return this.getUsername().compareTo(typeB.getUsername()); 
    else 
     return -1; // -1 means lesser than 
} 
+0

См. Мое редактирование. Я думаю, что базовая логика не изменится между вашим кодом и моим? – Sree

1

Существует элегантный способ решить эту проблему, и это не связано с уродливым compareTo trainwrecks.

  1. Pass через ваш список и сделать 2 SortedSet, один для A и один для B + C. Добавьте свои друзья в зависимости от их типа.
  2. Сделайте новый список и используйте способ Collections.addAll(), чтобы добавить в список 2 массива, которые вы можете получить из 2 SortedSet, сначала для A, затем для B+C.

Поскольку SortedSet сохранит содержимое в естественном порядке, который лексикографический для строк, окончательный список будет иметь тип A первые, отсортированный лексический, B and C после, также сортируется лексический.

+0

Я подумал об этом, но надеялся не делать этого, поскольку он казался неэлегантным. ты так не думаешь? – Sree

+0

По сравнению со всеми этими супер уродливыми компараторами это кажется мне довольно чистым. Нет, если (...) elseif (...) else {if (....) elsif (....) else {...}} = большой выигрыш. – Dave

+0

, поэтому вместо создания одного компаратора для приложения вы создадите 3 списка, действительно «красивый и чистый» способ – user902383