0

I'm new to actively writing questions here, although I've used this site for some time now.

I want to sort an ArrayList in lexicalic order (= natural order?!) depending on the first two indices of the array. Currently I've used the code below:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

public class SortArrayList {

    public static void main(String[] args) {

        ArrayList<String[]> workingSet = new ArrayList<>();
        workingSet.add(new String[]{"MiningCorp", "2265 Betacity"});
        workingSet.add(new String[]{"MiningCorp", "6454 Iotacity"});
        workingSet.add(new String[]{"Arbiter", "3812 Gammacity"});
        workingSet.add(new String[]{"MiningCorp", "1234 Thetacity"});
        workingSet.add(new String[]{"Arbiter", "1812 Deltacity"});

        Comparator<String[]> staComp = new Comparator<String[]>() {

            @Override
            public int compare(String[] first, String[] second) {
                String composite1 = first[0] + " " + first[1];
                String composite2 = second[0] + " " + second[1];
                return composite1.compareTo(composite2);
            }
        };

        Collections.sort(workingSet, staComp);
        for(String[] arr : workingSet){
            System.out.println(Arrays.toString(arr));
        }


    }

}

This should produce the following output:

[Arbiter, 1812 Deltacity]
[Arbiter, 3812 Gammacity]
[MiningCorp, 1234 Thetacity]
[MiningCorp, 2265 Betacity]
[MiningCorp, 6454 Iotacity]

This exactly what I wanted. Is there a more elegant way using prebuilt methods?

What if I wanted to sort by grouping by the first array entry in lexicalic order, but within this group i want the individual arrays to be sorted by inverse lexicalic order? For this, do I need a second comparator to first pre-sort the entries of the second index of each array?

Here is what i want to get for this example:

[Arbiter, 3812 Gammacity]
[Arbiter, 1812 Deltacity]
[MiningCorp, 6454 Iotacity]
[MiningCorp, 2265 Betacity]
[MiningCorp, 1234 Thetacity]

3 Answers 3

2

If java8 is an option, than I would use the thenComparing method to combine two sort specifiers.

When using reversed the result of a comparator will be upside down.

Example code:

// turn your list into a stream
workingSet.stream()

// sort it...
.sorted(

    // first sort specifier: 0th element of Array
    Comparator.<String[], String>comparing(composite -> composite[0])

        // combine sort specifiers
        .thenComparing(

                // second sort specifier: 2st element of Array
                Comparator.<String[], String>comparing(composite -> composite[1])

                // REVERSED!
                .reversed()
        )
    )

// convert each array to a String
.map(Arrays::toString)

// print each String
.forEach(System.out::println);
Sign up to request clarification or add additional context in comments.

Comments

2

What if I wanted to sort by grouping by the first array entry in lexicalic order, but within this group i want the individual arrays to be sorted by inverse lexicalic order?

Then you'll need to implement the Comparator differently:

Comparator<String[]> secondComparator = new Comparator<String[]>() {
        @Override
        public int compare(String[] first, String[] second) {
            int compareFirstPart = first[0].compareTo(second[0]);
            if(compareFirstPart != 0)
                return compareFirstPart;
            else
                return second[1].compareTo(first[1]); // Inverse!
        }
    };

Comments

1

If you use java 8, you may use lambda expressions as well :

Collections.sort(workingSet, (first, second) -> {
            int compareFirstPart = first[0].compareTo(second[0]);
            if(compareFirstPart != 0)
                return compareFirstPart;
            else
                return second[1].compareTo(first[1]); 
});

1 Comment

while lambda expressions are not entirely new for me, this makes it clearer for me how they work in java. Thank you for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.