0

May I know how can I sort a List<Object[]> and order by more than one element ?

below is my code: I retrieve my result from database using below code

public List<Object[]> readyToPrint() {
Query query = em.createNativeQuery("SELECT 
    so_order_no,so_bo_suffix,shortname1,ETD......;
    List<Object[]> allObject = query.getResultList(); 
   return allObject; 

}

As what I know I can only read the result using Object am I right ? So i think i don't have any specific class. Then if the result of element[X] meet certain condition, I want to edit the content of that element, and then only I resorting the result again.

Then i retrieve my result using below code:

`List<Object[]> allList = salesOrderFacade.readyToPrint();
readyToPrintResult = new ArrayList<>();

for (Object[] list : allList) {
    if (outgoingFacade.checkReadyToDelivery(list[0].toString(), list[1].toString())) {
        readyToPrintResult.add(list);
    } 
}

I want to sort myreadyToPrintResult` list by element 2 and follow by element 3.

I tried the code below;

Collections.sort(readyToPrintResult, new Comparator<Object[]>() { @Override public int compare(Object[] lines1, Object[] lines2) { return lines1[2].xxxxx; } });

but I stuck in the return part. I not able to use "compare" code.

Example: I have a List of result :

-Apple , 11-01-2017 , Y , N

-Bubble ,11-01-2017 , Y ,N

-Cat , 11-01-2017 , Y ,N

-Dora , 11-01-2017 , N ,Y

-Elephant,11-01-2017, N,Y

Then if Elephant meet some condition, I want to change the list of result of elephant to :

Elephant,11-01-2017, Y,N

Then I would like to sorting the whole list and my expected result is as below: -Apple , 11-01-2017 , Y , N

-Bubble ,11-01-2017 , Y ,N

-Cat , 11-01-2017 , Y ,N

-Elephant,11-01-2017, Y,N

-Dora , 11-01-2017 , N ,Y

Anyone can help? Thanks in advance

Ng Zheng
  • 59
  • 1
  • 12
  • 2
    What's the actual type of the elements of your arrays? – Eran May 09 '17 at 10:54
  • 2
    Your problem stems from the fact that having a `List` is not a good idea. You either want `List>` or, **much** better yet, `List>` – Michael May 09 '17 at 10:54
  • 2
    Possible duplicate of [How to use Comparator in Java to sort](http://stackoverflow.com/questions/2839137/how-to-use-comparator-in-java-to-sort) – mornaner May 09 '17 at 10:55
  • 1
    It is not clear what exactly the contents of your List are. It would be helpful if you gave us a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) and the expected result of the sorting – Robin Topper May 09 '17 at 10:55
  • in java `Object` class is evil, don't use it :). use generic instead : https://www.tutorialspoint.com/java/java_generics.htm – nafas May 09 '17 at 11:09
  • Dear all.. Thanks for your comment and answer.. I have updated my question... I think my question is not clear enough.. Sorry about that – Ng Zheng May 11 '17 at 04:25

3 Answers3

0

By declaring the Object type in the Comparator declaration, you get two Object parameters to compare in the compare() method.
So, you can invoke only Object methods on them and besides Object doesn't implement the Comparable interface.
With the Object declared class, finally,you have not a lot of way to exploit it but a tricky use of the toString().

Whereas the error :

But I got stuck on the return part. I'm not able to use compare code

return lines1[2].xxxxx;

You have two ways :

  • you work with more specific class than Object[]. For example : Line[] (as you name it in this way).

In this way, you may specify the Line type in the Comparator declaration :

Collections.sort(readyToPrintResult, new Comparator<Line[]>() {
    @Override
    public int compare(Line[] lines1, Line[] lines2) {
        return lines1[2].getValue().compareTo(lines2[2].getValue());
    }
});

It is the finer solution.

  • If you cannot work with a more specific class than Object[] because you manipulate objects with distinct(and not derived) classes , you could check the type of the two parameters and cast them in the compare() method.
    It is a really not advised way because you will have to perform a a lot of boiler plate code, casts and handling the cases when the two values doesn't rely on the same type.
davidxxx
  • 125,838
  • 23
  • 214
  • 215
0

The int returned by the compare code is based on your parameters.

If the first one (lines1[2]) is less than your second parameter (lines2[2]) then your compare method should return a negative integer.

If lines1[2] is greater than lines2[2] you return a positive integer.

If lines1[2] and lines2[2] are the same you could return 0 (and quit comparing these objects) or as you want it compare lines1[3] against lines2[3]. Here you have to check again and then return a negative or positive number or 0.

M. Haverbier
  • 383
  • 2
  • 13
0

Replace ActualType with any type you expect that is Comparable (I suppose it most likely would be String):

readyToPrintResult.sort((o1, o2) -> {
    int res = ((ActualType) o1[2]).compareTo((ActualType) o2[2]);
    return res != 0 ? res : ((ActualType) o1[3]).compareTo((ActualType) o2[3]);
});
Nestor Sokil
  • 2,162
  • 12
  • 28