I am having Map
s 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;
}
}
Output 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}]
Output 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}]
Output 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}]
CodePudding user response:
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
Object
as generic type. Generics were introduced to enforce the type safety, usingObject
as 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
instanceof
checks and type casting. - Don't write your code against concrete classes like
LinkedHashMap
- variable type has to beMap
instead.
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