2014-12-08 4 views
1

Это то, что у меня есть до сих пор, я пытаюсь сортировать кучу List<String>'s на основе значения индекса.Список сортировки на основе значения индекса

LinkedHashSet<List<String>> sorted = new LinkedHashSet<List<String>>(); 

Как я отсортировать LinkedHashSet в порядке от высокого до самого низкого индекса 2 значения из Листа?

Пример входных данных:

List<String> data1 = Database.getData(uuid); 
double price = Double.valueOf(data1.get(2)) 

data1.add("testval"); 
data1.add("testval"); 
data1.add("100.00"); 

sorted.add(data1); 

и на другом отдельном списке:

List<String> data2 = Database.getData(uuid); 
double price = Double.valueOf(data2.get(2)) 

data2.add("anotherval"); 
data2.add("anotherval"); 
data2.add("50.00"); 

sorted.add(data2); 

Вывод отсортированного LinkedHashSet в порядке убывания.

testval testval 100.00 
anotherval anotherval 50.00 

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

+1

Возможный дубликат: http://stackoverflow.com/ questions/17370909/sorting-a-linkedhashset – runDOSrun

+0

Является ли значение всегда третьим элементом в списке? – xcoder

+0

Да, значение всегда совпадает с индексом – ThatGuy343

ответ

3

Создайте новый класс для представления сложных объектов. Нет необходимости хранить несколько значений в списке, когда вы можете сделать это в объектах.

public class ComplexObject { 
    private String description1; 
    private String description2; 
    private Double value; 

    public ComplexObject(String description1, String description2, Double value) { 
     this.description1 = description1; 
     this.description2 = description2; 
     this.value = value; 
    } 

    public void setDescription1(String description1) { 
     this.description1 = description1; 
    } 

    public String getDescription1() { 
     return description1; 
    } 

    public void setDescription2(String description2) { 
     this.description2 = description2; 
    } 

    public String getDescription2() { 
     return description2; 
    } 

    public void setValue(Double value) { 
     this.value = value; 
    } 

    public Double getValue() { 
     return value; 
    } 
} 

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

public static void main(String[] args) { 

    List<ComplexObject> complexObjectList = new ArrayList<ComplexObject>(); 

    //add elements to the list 
    complexObjectList.add(new ComplexObject("testval","testval",100.00d)); 
    complexObjectList.add(new ComplexObject("anotherval","anotherval",50.00d)); 

    //sort the list in descending order based on the value attribute of complexObject 
    Collections.sort(complexObjectList, new Comparator<ComplexObject>() { 
      public int compare(ComplexObject obj1, ComplexObject obj2) { 
       return obj2.getValue().compareTo(obj1.getValue()); //compares 2 Double values, -1 if less , 0 if equal, 1 if greater 
      } 
     }); 

    //print objects from sorted list 
    for(ComplexObject co : complexObjectList){ 
     System.out.println(co.getDescription1()+" "+co.getDescription2()+" "+co.getValue()); 
    } 
} 

Выход:

 
testval testval 100.0 
anotherval anotherval 50.0 
+0

Это работает, однако только после того, как я отменил заказ. Collections.reverse (complexObjectList); – ThatGuy343

+0

Это идея, просто примечание к вашему коду: если ваши геттеры и сеттеры используются только для получения ссылок и передачи значений для установки, не считаете ли вы, что было бы проще сделать атрибуты общедоступными и избежать шаблонных кодов ? –

+0

@ PabloFranciscoPérezHidalgo Я бы сказал, что ComplexObject должен быть неизменным, удалять сеттеры. В противном случае вы рискуете изменить объекты после сортировки. Я бы предпочел увидеть конструктор с частными полями и просто геттеры. Я не думаю, что getters/seters являются шаблонами, они легко генерируются IDE и добавляют что-то полезное в микс. –

3

Во-первых, и экстрагируют из Oracle's Java reference:

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

Таким образом, вы не можете сортировать данные просто вставляют его в LinkedHashSet. Возможно, вы сбиваете с толку эту реализацию набора с помощью SortedSet. SortedSet позволяет передавать компаратор, который будет определять порядок элементов в структуре данных.

С другой стороны, я не знаю, выбрали ли вы вас List<String> произвольно, но мне кажется более разумной возможность объединить ваши 3 строки в качестве атрибутов класса. Дело в том, что если ваши элементы всегда будут 3-мя элементами, последнее значение будет двойным: зачем нужна динамическая структура как List?

EDIT

Здесь у вас есть возможное лучшее выполнение того, что вы хотите:

public class Element 
{ 
    public Element(String a, String b, double val) { 
     this.a = a; 
     this.b = b; 
     this.val = val; 
    } 

    @Override 
    public String toString() { 
     return a + "\t" + b + "\t" + val; 
    } 

    public String a; 
    public String b; 
    public double val; 
} 

И вы можете использовать этот класс для хранения элементов. Пример использования:

SortedSet<Element> sorted = new TreeSet<>(new Comparator<Element>() { 
     @Override 
     public int compare(Element o1, Element o2) { 
      return (new Double(o1.val)).compareTo(o2.val); 
     } 
    }); 

sorted.add(new Element("testval", "testval", 100.0)); 
sorted.add(new Element("anotherval", "anotherval", 50.0)); 
for(Element el: sorted) 
{ 
    System.out.println(el); 
} 

Обратите внимание, что компаратор дается как экземпляр anonympous внутреннего класса, реализующего интерфейс в Java Comparator.

+0

Можете ли вы привести пример передачи компаратора с этим сценарием? – ThatGuy343

+0

@ ThatGuy343 Done :) –

+0

Попытка этого. – ThatGuy343

3
  • Во-первых, вы не должны использовать LinkedHashSet, но TreeSet. LinkedHashSet сохранит порядок вставки без сортировки.
  • Во-вторых, вы должны инициализировать ваш TreeSet с Comparator, что сопоставляются на основе какой бы ни стоимости вашего List требуется, то есть, если вы знаете индекс String, который будет представлять значение double заранее.В противном случае я бы рекомендовал использовать пользовательские объекты вместо List.

Если вы решили использовать пользовательские объекты, вы не обязательно должны инициализировать TreeSet с Comparator в качестве второго аргумента.

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

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

Наконец, пользовательские объекты потребуют от вас переопределить equals и hashCode.

+0

Мне кажется, что Я должен использовать объекты. – ThatGuy343

+0

@ ThatGuy343 не 'Объект', заметьте. Пользовательские объекты. Что-то вроде 'MyTransferObject', с геттерами/сеттерами для соответствующих полей. – Mena

Смежные вопросы