Reputation: 3
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
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
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
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
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
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
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
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