I am having Maps inside a List.
I need to sort the List based on the input dynamically by passing it as a parameter into the method sortData.
It is working as expected, but the problem is that am not able to sort the list in reverse order.
I’m getting an Error : The method get(String) is undefined for the type Object
Code
public class TestingClass {
public static void main(String[] args) {
List< LinkedHashMap<String,Object> > list = new ArrayList<>();
/*Map 2*/
LinkedHashMap<String,Object> lhm1 = new LinkedHashMap<>();
lhm1.put("LONG_HEADER", 2l);
lhm1.put("STRING_HEADER1", "C");
lhm1.put("STRING_HEADER2", "D");
/*Map 2*/
LinkedHashMap<String,Object> lhm2 = new LinkedHashMap<>();
lhm2.put("LONG_HEADER", 1l);
lhm2.put("STRING_HEADER1", "E");
lhm2.put("STRING_HEADER2", "F");
/*Map 3*/
LinkedHashMap<String,Object> lhm3 = new LinkedHashMap<>();
lhm3.put("LONG_HEADER", 3l);
lhm3.put("STRING_HEADER1", "A");
lhm3.put("STRING_HEADER2", "B");
list.add(lhm1);
list.add(lhm2);
list.add(lhm3);
List< LinkedHashMap<String,Object> > sortedList1 = sortData(list,"LONG_HEADER","ASC" );
System.out.println("Output 1 After sorting" +sortedList1);
List< LinkedHashMap<String,Object> > sortedList2 = sortData(list,"STRING_HEADER1","ASC" );
System.out.println("Output 2 After sorting"+sortedList2);
List< LinkedHashMap<String,Object> > sortedList3 = sortData(list,"STRING_HEADER2","ASC" );
System.out.println("Output 3 After sorting"+sortedList3);
/* It won't work */
sortData(list,"LONG_HEADER","DESC" );
sortData(list,"STRING_HEADER1","DESC" );
sortData(list,"STRING_HEADER2","DESC" );
}
private static List<LinkedHashMap<String, Object>> sortData(List<LinkedHashMap<String, Object>> inputGridData,
String sortBy, String sortOrder) {
List<LinkedHashMap<String, Object>> lOutputGridDat = null;
if (inputGridData.get(0).get(sortBy) instanceof Long) {
if( "ASC".equals(sortOrder)) {
lOutputGridDat = inputGridData.stream().sorted(Comparator.comparingLong(o -> ((Long) o.get(sortBy))))
.collect(Collectors.toList());
}
else {
/*Here am getting error if i use .reversed() method*/
//Error : The method get(String) is undefined for the type Object
lOutputGridDat = inputGridData.stream().sorted(Comparator.comparingLong(o -> ((Long) o.get(sortBy))).reversed())
.collect(Collectors.toList());
}
} else {
if( "ASC".equals(sortOrder)) {
lOutputGridDat = inputGridData.stream().sorted(Comparator.comparing(o -> ((String) o.get(sortBy))))
.collect(Collectors.toList());
}
else {
/*Here am getting error if i use .reversed() method*/
// Error : The method get(String) is undefined for the type Object
lOutputGridDat = inputGridData.stream().sorted(Comparator.comparing(o -> ((String) o.get(sortBy))).reversed())
.collect(Collectors.toList());
}
}
return lOutputGridDat;
}
}
Map 1 After sorting
[{LONG_HEADER=1, STRING_HEADER1=E, STRING_HEADER2=F}, {LONG_HEADER=2, STRING_HEADER1=C, STRING_HEADER2=D}, {LONG_HEADER=3, STRING_HEADER1=A, STRING_HEADER2=B}]
Map 2 After sorting
[{LONG_HEADER=3, STRING_HEADER1=A, STRING_HEADER2=B}, {LONG_HEADER=2, STRING_HEADER1=C, STRING_HEADER2=D}, {LONG_HEADER=1, STRING_HEADER1=E, STRING_HEADER2=F}]
Map 3 After sorting
[{LONG_HEADER=3, STRING_HEADER1=A, STRING_HEADER2=B}, {LONG_HEADER=2, STRING_HEADER1=C, STRING_HEADER2=D}, {LONG_HEADER=1, STRING_HEADER1=E, STRING_HEADER2=F}]
Advertisement
Answer
Firstly, it’s worth to point out at some important issues with the code you’ve provided :
- As I’ve said, it’s not a good practice to use
Objectas generic type. Generics were introduced to enforce the type safety, usingObjectas generic type is as bad as don’t use generics at all. - Don’t store the elements of different types together in a single collection. And avoid
instanceofchecks and type casting. - Don’t write your code against concrete classes like
LinkedHashMap– variable type has to beMapinstead.
You can find more elaborate explanation on all account mentioned above on this site if you doubt if these suggestions have a value.
With regard to your question, comparators as defined in your’r code will not compile.
That’s you can fix it:
Comparator.<Map<String, Object>, String>comparing(
o -> ((String) o.get(sortBy))).reversed()
When you’re chaining the methods, the compiler is unable to infer the type of the prameter o inside the comparing based on the type of the elements of the stream.
Parameter o is treated not as a Map but as Object therefore you can’t invoke get() on it.
Generic type information needs to be provided explicitly: <Map<String, Object>, String>. Where the first part – type of the argument passed into comparing (i.e. element of the stream), the second is a type of value that will be used for comparison (i.e. string).
for information on the syntax of generic methods, take a look at this tutorial