User007
User007

Reputation: 3

Sorting on list of objects with more than one column using java

I have data like this name,order,estimate,actual

"Id1",4,230,350
"Id2",1,530,340
"Id3",4,530,150
"Id4",1,660,540
"Id5",2,530,540
"Id6",3,650,230
"Id7",4,530,120
"Id8",3,650,330

Need to sort them using order, estimate and actual values, output should look like

"Id2",1,530,340
"Id4",1,660,540
"Id5",2,530,540
"Id6",3,650,230
"Id8",3,650,330
"Id1",4,230,350
"Id7",4,530,120
"Id3",4,530,150

what is the best data structure to use and how to sort them on just integer values order,estimate,actual not on name

Upvotes: 0

Views: 2414

Answers (7)

User007
User007

Reputation: 3

I was able to use comparator and have the data in Map> and work out a solution

public class SortMapOnValueInteger {

    public static void main(String[] args) {

        Map<String, List<Integer>> unsortMap = new HashMap<String, List<Integer>>();
        unsortMap.put("z", new ArrayList(Arrays.asList( 3, 1, 56)));
        unsortMap.put("b", new ArrayList(Arrays.asList( 0, 2, 65)));
        unsortMap.put("x", new ArrayList(Arrays.asList( 0, 2, 35)));
        unsortMap.put("a", new ArrayList(Arrays.asList( 3, 3, 12)));
        unsortMap.put("c", new ArrayList(Arrays.asList( 1, 4, 65)));
        unsortMap.put("d", new ArrayList(Arrays.asList( 2, 4, 65)));
        unsortMap.put("e", new ArrayList(Arrays.asList( 4, 3, 34)));
        unsortMap.put("y", new ArrayList(Arrays.asList( 4, 2, 23)));
        unsortMap.put("n", new ArrayList(Arrays.asList( 3, 1, 23)));
        unsortMap.put("j", new ArrayList(Arrays.asList( 2, 2, 54)));
        unsortMap.put("m", new ArrayList(Arrays.asList( 1, 3, 96)));
        unsortMap.put("f", new ArrayList(Arrays.asList( 0, 4, 54)));

        System.out.println("Unsort Map......");
        printMap(unsortMap);

        System.out.println("\nSorted Map......");
        Map<String, List<Integer>> sortedMap = sortByComparator(unsortMap);
        printMap(sortedMap);

    }

    private static Map<String, List<Integer>> sortByComparator(Map<String, List<Integer>> unsortMap) {

        // Convert Map to List
        List<Map.Entry<String, List<Integer>>> list;
        list = new ArrayList<>(unsortMap.entrySet());


        // Sort list with comparator, to compare the Map values
        Collections.sort(list, new Comparator<Map.Entry<String, List<Integer>>>() {
            public int compare(Map.Entry<String, List<Integer>> o1,
                                           Map.Entry<String, List<Integer>> o2) {               
                int comparison = Integer.compare(o1.getValue().get(0), o2.getValue().get(0));
                if (comparison != 0) return comparison;
                    comparison = Integer.compare(o1.getValue().get(1), o2.getValue().get(1));
                if (comparison != 0) return comparison;
                    return Integer.compare(o1.getValue().get(2), o2.getValue().get(2));             
            }
        });         

        // Convert sorted map back to a Map
        Map<String, List<Integer>> sortedMap = new LinkedHashMap<String, List<Integer>>();
        for (Iterator<Map.Entry<String, List<Integer>>> it = list.iterator(); it.hasNext();) {
            Map.Entry<String, List<Integer>> entry = it.next();
            sortedMap.put(entry.getKey(), entry.getValue());
        }
        return sortedMap;
    }

    public static void printMap(Map<String, List<Integer>> map) {
        for (Map.Entry<String, List<Integer>> entry : map.entrySet()) {
            System.out.println("[Key] : " + entry.getKey() 
                                      + " [Value] : " + entry.getValue());
        }
    }

}

the output of sorted map is

Unsort Map......
[Key] : f [Value] : [0, 4, 54]
[Key] : d [Value] : [2, 4, 65]
[Key] : e [Value] : [4, 3, 34]
[Key] : b [Value] : [0, 2, 65]
[Key] : c [Value] : [1, 4, 65]
[Key] : a [Value] : [3, 3, 12]
[Key] : n [Value] : [3, 1, 23]
[Key] : m [Value] : [1, 3, 96]
[Key] : j [Value] : [2, 2, 54]
[Key] : z [Value] : [3, 1, 56]
[Key] : y [Value] : [4, 2, 23]
[Key] : x [Value] : [0, 2, 35]

Sorted Map......
[Key] : x [Value] : [0, 2, 35]
[Key] : b [Value] : [0, 2, 65]
[Key] : f [Value] : [0, 4, 54]
[Key] : m [Value] : [1, 3, 96]
[Key] : c [Value] : [1, 4, 65]
[Key] : j [Value] : [2, 2, 54]
[Key] : d [Value] : [2, 4, 65]
[Key] : n [Value] : [3, 1, 23]
[Key] : z [Value] : [3, 1, 56]
[Key] : a [Value] : [3, 3, 12]
[Key] : y [Value] : [4, 2, 23]
[Key] : e [Value] : [4, 3, 34]

Upvotes: 0

Navish Sharma
Navish Sharma

Reputation: 243

I would suggest using a different class as mentioned in my previous answer but still if you cannot avoid it,you can have a data structure like this:

Map<String, List<Integer>> dataMap = new HashMap<String, List<Integer>>();

where the key would be the ID and the list would contain the order,estimate and actual values.Remember that list is an ordered collection so you should add your values in the same sequence for all entries of Map.E.g:

        String key1 = "Id1";
        List<Integer> valueList1 = new ArrayList<Integer>();
        valueList1.add(4);     //order
        valueList1.add(230);   //estimate
        valueList1.add(350);   //actual
        dataMap.put(key1, valueList1); 

        String key2 = "Id2";
        List<Integer> valueList2 = new ArrayList<Integer>();
        valueList2.add(1);
        valueList2.add(530);
        valueList2.add(340);
        dataMap.put(key2, valueList2);

        //add all values similarly

Your dataMap will be look like:

{Id4=[1, 660, 540], Id3=[4, 530, 150], Id6=[3, 650, 230], Id5=[2, 530, 540], Id8=[3, 650, 330], Id7=[4, 530, 120], Id2=[1, 530, 340], Id1=[4, 230, 350]}

You might have noticed that the values are not in the order in whic you had put.This is because the put method does not guarantee the order in which elements are put into the Map.

Now you are done with the data structure part.For sorting you can implement this method in your class

@SuppressWarnings({ "unchecked", "rawtypes" })
public Map sortByValue(Map map) {
    List list = new LinkedList(map.entrySet());
    Collections.sort(list, new Comparator() {
        public int compare(Object o1, Object o2) {
        //Your custom sorting logic 
            if (((List<Integer>) (((Map.Entry) (o1)).getValue())).get(0) > ((List<Integer>) (((Map.Entry) (o2))
                        .getValue())).get(0)) {
                    return 1;
                } else if (((List<Integer>) (((Map.Entry) (o1)).getValue()))
                        .get(0) < ((List<Integer>) (((Map.Entry) (o2))
                        .getValue())).get(0)) {
                    return -1;
                } else {
                    if (((List<Integer>) (((Map.Entry) (o1)).getValue()))
                            .get(1) > ((List<Integer>) (((Map.Entry) (o2))
                            .getValue())).get(1)) {
                        return 1;
                    } else if (((List<Integer>) (((Map.Entry) (o1)).getValue()))
                            .get(1) < ((List<Integer>) (((Map.Entry) (o2))
                            .getValue())).get(1)) {
                        return -1;
                    } else {
                        if (((List<Integer>) (((Map.Entry) (o1)).getValue()))
                                .get(2) > ((List<Integer>) (((Map.Entry) (o2))
                                .getValue())).get(2)) {
                            return 1;
                        } else if (((List<Integer>) (((Map.Entry) (o1))
                                .getValue())).get(2) > ((List<Integer>) (((Map.Entry) (o2))
                                .getValue())).get(2)) {
                            return -1;
                        } else {
                            return 0;
                        }
                    }
                }
            }
        });

        Map result = new LinkedHashMap();
        for (Iterator it = list.iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

The result would be:

{Id2=[1, 530, 340], Id4=[1, 660, 540], Id5=[2, 530, 540], Id6=[3, 650, 230], Id8=[3, 650, 330], Id1=[4, 230, 350], Id3=[4, 530, 150], Id7=[4, 530, 120]}

Upvotes: 0

BluesSolo
BluesSolo

Reputation: 608

I always use Comparator. If you don't want to create a new class you could do it like this:

    ArrayList<Data> data = new ArrayList<Data>();
    // ....
    data.add(new Data("Id1", 4, 230, 350));
    data.add(new Data("Id2", 1, 530, 340));
    data.add(new Data("Id3", 3, 340, 340));
    data.add(new Data("Id4", 2, 300, 200));
    // ....
    System.out.println("Unsorted: " + data);
    data.sort(new Comparator<Data>() {

        @Override
        public int compare(Data o1, Data o2) {
            if(o1.x > o2.x)
            {
                return 1;
            }
            else
            {
                return -1;
            }
        }
    });
    System.out.println("Sorted by x: " + data);

Gives you the wished output:

    Unsorted: [Id1, Id2, Id3, Id4]
    Sorted by x: [Id2, Id4, Id3, Id1]

Assuming you have the data stored like this:

public class Data {

        Data(String id, int x, int y, int z)
        {
            this.id = id;
            this.x = x;
            this.y = y;
            this.z = z;
        }
        String id;
        int x; // Sort by x
        int y;
        int z;

        @Override
        public String toString() {
            return id;
        }       
    }

Upvotes: 0

Navish Sharma
Navish Sharma

Reputation: 243

You can create a class with properties order,estimate and actual values something like this

public class Data {
    private String name;
    private int order;
    private int estimate;
    private int actual;

}

For sorting you can have a list as data structure and use Array List implementation

List<Data> dataList=new ArrayList<Data>();

Implement the Comparator interface in a class and write your sorting logic in the compare method

public int compare(Data data1, Data data2) {
//your sorting logic based on order,estimate,actual 
}

and in the class where you want to sort use:

Comparator<Data> dataComparator = new DataComparator();
 Collections.sort(dataList, dataComparator);

Using a separate comparator instead of comparable has an advantage of segregating the sorting logic in a separate class.

Upvotes: 1

sTg
sTg

Reputation: 4434

Use the method that accepts a Comparator when you want to sort and pass it to Collections.sort(List, Comparator)

For Eg:

class myClass implements Comparator<object> {

    @Override
    public int compare(object o1, object o2) {
        // write comparison logic here 
        return o1.getID().compareTo(o2.getID());
    }
}

Then use the Comparator as

Collections.sort(objectData,new myClass());

You can modify the logic as per your requirements.

Upvotes: 1

Suresh Sajja
Suresh Sajja

Reputation: 562

Write a class that implements Comparable

public class MyObject implements Comparable<MyObject>
{

private String id;
private  int order;
private int estimate;
private int actualValue;

@Override
public int compareTo(MyObject o)
{
    //Define your logic
    return 0;
}
}

You can use list or set (depends on what you want to do) to store these objects and sort them using sort method

List<MyObject> list = new ArrayList<>();
    //list.add();
Collections.sort(list);

Upvotes: 1

jjlema
jjlema

Reputation: 860

Create a record that implements comparable and then put your records in a list and call:

Collections.sort(list);

Record is:

import java.util.Collections;
import org.apache.commons.lang.builder.CompareToBuilder;

public class Record implements Comparable<Record> {
String cad;
Integer x, y, z;

public int compareTo(final Record o) {
    return new CompareToBuilder().append(this.x, o.x).append(this.y, o.y).append(this.z, o.z).toComparison();
}

}

Upvotes: 1

Related Questions