Sort List based on index value

2k Views Asked by At

This is what i have so far, i'm trying to sort a bunch of List<String>'s based on the value of an index.

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

How do i sort the LinkedHashSet in order from Highest to Lowest index 2 value of the List's?

Example input:

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);

and on another seperate List:

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);

Output of the sorted LinkedHashSet in descending order.

testval testval 100.00
anotherval anotherval 50.00

Sorry if this is confusing, im not sure where to go about sorting like this.

3

There are 3 best solutions below

6
On BEST ANSWER

Create a new class to represent you complex objects. There is no need to store multiple values in a list when you can do it in objects.

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;
    }
}

Then add elements to the list and sort it using a new, custom, comparator:

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());
    }
}

Output:

testval testval 100.0
anotherval anotherval 50.0
4
On

First, and extracted from Oracle's Java reference:

This linked list defines the iteration ordering, which is the order in which elements were inserted into the set

So you can't sort your data just inserting it into the LinkedHashSet. You may be confusing that set implementation with SortedSet. SortedSet allows you to pass a comparator which will determine the elements order in the data structure.

On the other hand, I don't know whether you chose you List<String> arbitrarily but it seems to me a wiser option to aggregate your the 3 strings as a class attributes. The point is that, if your elements are always going to be 3 elements, being the last one a double value: Why do you need a dynamic structure as a List?

EDIT

Here you have a possible better implementation of what you want:

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;
}

And you can use this class to store your elements. An example of use:

 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);
}

Note that the comparator is given as an instance of an anonympous inner class implementing Java's Comparator interface.

2
On
  • Firstly, you shouldn't use a LinkedHashSet but a TreeSet. LinkedHashSet will retain the insertion order without sorting.
  • Secondly, you need to initialize your TreeSet with a Comparator that compares based on whichever value of your List is required, that is, if you know the index of the String that will represent a double value in advance. Otherwise I would recommend using custom objects instead of List.

If you decide to use custom objects, you don't necessarily need to initialize your TreeSet with a Comparator as second argument.

Instead, you could have your custom objects implement Comparable, and implement a one-time comparation logic there.

It all depends on whether you only need to sort in a particular order.

Finally, custom objects will require you to override equals and hashCode.