14

What is the best way to sort an ArrayList<String[]> in Java?

Where String[] is...

String[] strAarray = new String[] { "abc", "abc", "abc", "abc", "abc", "abc", "abc" };

Now I want to sort the whole ArrayList by the 2nd value of String[] (at index 1). I need to loop through each and every String[] and then its child at index 1.

Any ideas?

Edit:


I have more descriptions. I am actually getting schools from some XML file and every node in XML has 7 attributes. Now I am creating an ArrayList of String[] which is holding those school nodes from XML and String[] strArray itself is holding attributes of particular node.

Now, the way I want to sort it is, it should sort according to State of school which is the 2nd attribute in XML and index 1 in String[] inside ArrayList.

I need to loop through each and every School first (node in XML, String[] in Java) and then I will have to filter State (State attribute in XML, String[1] in Java).

Mahan Vyakti
  • 129
  • 3
  • 10
Umair A.
  • 6,690
  • 20
  • 83
  • 130
  • 3
    I don't see any ArrayList anywhere, and everything in your string array is identical... – BoltClock Jan 15 '11 at 13:28
  • 1
    Please try explain it a bit futher, post some input parameters and excepted results. – Crozin Jan 15 '11 at 13:30
  • You would be well served by using objects instead of lists, arrays, and strings. Java's an object-oriented language. You're having trouble because you're thinking at too low a level XML is not a good abstraction. – duffymo Nov 19 '19 at 16:23

7 Answers7

36

Start with Collections.sort, the one that takes a custom Comparator. You'll need to write a custom Comparator for this also.

For instance, assuming you want to rely on the natural ordering of Strings as defined in their compareTo method:

public static void main(String[] args) throws Exception {
        ArrayList<String[]> listOfStringArrays = new ArrayList<String[]>();
        listOfStringArrays.add(new String[] {"x","y","z"});
        listOfStringArrays.add(new String[] {"a","b","c"});
        listOfStringArrays.add(new String[] {"m","n","o"});
        Collections.sort(listOfStringArrays,new Comparator<String[]>() {
            public int compare(String[] strings, String[] otherStrings) {
                return strings[1].compareTo(otherStrings[1]);
            }
        });
        for (String[] sa : listOfStringArrays) {
            System.out.println(Arrays.toString(sa));
        }
        /* prints out 
          [a, b, c]
          [m, n, o]
          [x, y, z]
        */ 

    }
whaley
  • 16,075
  • 10
  • 57
  • 68
  • Note that this is actually sorting by index 1. If you change the "y" to "a" then it'll print out as is ordered. – KingLogic Jul 04 '21 at 06:23
  • I'm not sure I understand this comment. The question asks for sorting based on index 1. The order of the input does't matter. – whaley Jul 04 '21 at 11:55
4

You create a Comparator<String[]> like so:

new Comparator<String[]>() {
  public int compare(String[] first, String[] second) {
    return first[1].compareTo(second[1]);
  }
}

then pass it to Collections.sort().

You might want to do some checking if the second element is actually present in the array. You could also do a custom comparison if the standard String comparison isn't enough.

Jorn
  • 20,612
  • 18
  • 79
  • 126
  • I am thinking how it would sort the whole ArrayList by State in ascending order? – Umair A. Jan 15 '11 at 13:41
  • 1
    It would be in ascending order the way both Jorn and I presented it. if you wanted it in another order, then you could either negate the value returned from String.compareTo(String) or just call Collections.reverse(yourList) after you've sorted the first time. – whaley Jan 15 '11 at 13:46
3

This is extremely easy to do with Java 8. Just write:

list.sort(Comparator.comparing(a -> a[1]));

For example, the following code:

List<String[]> list = Arrays.asList(
    new String[] { "abc", "abc", "abc", "abc", "abc", "abc", "abc" },
    new String[] { "xyz", "xyz", "xyz", "xyz", "xyz", "xyz", "xyz" },
    new String[] { "fgh", "fgh", "fgh", "fgh", "fgh", "fgh", "fgh" });

list.sort(Comparator.comparing(a -> a[1]));
list.stream().map(Arrays::toString).forEach(System.out::println);

Will yield the wanted result:

[abc, abc, abc, abc, abc, abc, abc]
[fgh, fgh, fgh, fgh, fgh, fgh, fgh]
[xyz, xyz, xyz, xyz, xyz, xyz, xyz]
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
3

You write a Comparator that compares two String[] by the correct child, and then you pass it to Collections.sort(List<T> list, Comparator<? super T> c).

Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
0

Use TreeSet or TreeMap http://download.oracle.com/javase/6/docs/api/java/util/TreeSet.html

Navi
  • 8,580
  • 4
  • 34
  • 32
0

Based on your edit: Your String[] should be a School object to contain your attributes. Make your School object implement Comparable and that will allow easy sorting with Collections.sort().

jzd
  • 23,473
  • 9
  • 54
  • 76
0

Suppose we have a list of arrays [["x", "y","z"], ["a", "b", "c"], ["m", "n", "o"]]

We can use list.sort() instead of Collections.sort().

To sort, we can adopt a cleaner way using lambdas and method references.

Using lambda:

listOfStrings.sort((a, b)->a[1].compareTo(b[1]));

Using method reference:

listOfStrings.sort(Comparator.comparing(a->a[1]));

Outputs:

[a, b, c]
[m, n, o]
[x, y, z]
Ankit Sharma
  • 1,626
  • 1
  • 14
  • 21