'Sorting a 2D List containing both Strings and Integers, sort by integers asc how do i do? (JAVA)

          theList.add(new 2DList("abc123", 9986));
          theList.add(new 2DList("ads314", 1234));
          theList.add(new 2DList("dal192", 3214));
          theList.add(new 2DList("sam273", 9823));
          theList.add(new 2DList("wor213", 7643));
          theList.add(new 2DList("wos987", 1292));
          theList.add(new 2DList("cat202", 9382));
          theList.add(new 2DList("jga213", 9432));
          theList.add(new 2DList("gog113", 1493));
          theList.add(new 2DList("aba231", 9831));

I want to sort the Integers by lowest to highest and by doing so also sort the Strings and save the sorted array in a new array.

maybe by using collector java compare? but I don't really know how, I would like to learn.

What if I want to sort a sequence by String and another by Integer? How do I choose between two values I want to sort by integer and then others by String.



Solution 1:[1]

List<2DList> sortedList = theList.stream().sorted(Comparator.comparing(2DList::getValue)).collect(Collectors.toList());

If you want to get the values out in separate lists:

List<Integer> valueList = theList.stream().map(v -> v.getValue()).sorted().collect(Collectors.toList());
List<String> nameList = theList.stream().map(v -> v.getName()).sorted().collect(Collectors.toList());

Solution 2:[2]

I would use a stable sort algorithm on the numbers, and then on the strings. Here's the sample code.

import java.util.*;
class DList{
    DList(String n, int v){ name =n; value=v;}
    String name;
    int value;
    public String toString(){
        return "DList[" + name + ", " + value + "]";
    }
}
public class Main{
    public static void main(String[] args) {
        List<DList> theList = new ArrayList<>();
          theList.add(new DList("abc123", 9986));
          theList.add(new DList("ads314", 1234));
          theList.add(new DList("dal192", 3214));
          theList.add(new DList("sam273", 9823));
          theList.add(new DList("wor213", 7643));
          theList.add(new DList("wos987", 1292));
          theList.add(new DList("cat202", 9382));
          theList.add(new DList("jga213", 9432));
          theList.add(new DList("gog113", 1493));
          theList.add(new DList("aba231", 9831));
          
          theList.forEach(System.out::println);
          System.out.println("==============");
          theList.sort((e1,e2)->{return e1.value-e2.value;});
          theList.sort((e1,e2)->{return e1.name.compareTo(e2.name);});
          theList.forEach(System.out::println);
    }
}

Output:

DList[ads314, 1234]
DList[wos987, 1292]
DList[gog113, 1493]
DList[dal192, 3214]
DList[wor213, 7643]
DList[cat202, 9382]
DList[jga213, 9432]
DList[sam273, 9823]
DList[aba231, 9831]
DList[abc123, 9986]
==============
DList[aba231, 9831]
DList[abc123, 9986]
DList[ads314, 1234]
DList[cat202, 9382]
DList[dal192, 3214]
DList[gog113, 1493]
DList[jga213, 9432]
DList[sam273, 9823]
DList[wor213, 7643]
DList[wos987, 1292]

Solution 3:[3]

First, allocate a record to hold the string and ints. A record is an immutable class. A class could also be used.

record Data(String getString, int getValue) {
    @Override
    public String toString() {
        return String.format("[%s, %s]", getString, getValue);
    }
}

Now create a list of data records.

List<Data> theList = new ArrayList<>(List.of(new Data("abc123", 9986),
        new Data("ads314", 1234), new Data("dal192", 3214),
        new Data("sam273", 9823), new Data("wor213", 7643),
        new Data("wos987", 1292), new Data("cat202", 9382),
        new Data("jga213", 9432), new Data("gog113", 1493),
        new Data("aba231", 9831)));

And start the sorting process.

  • sort the original list
  • add to a new list byString
  • print the sorted strings.
  • repeat the process for ints storing in byValue
theList.sort(Comparator.comparing(Data::getString));
List<Data> byString = new ArrayList<>(theList);
System.out.println("Sorted by String\n");
byString.forEach(System.out::println);

theList.sort(Comparator.comparing(Data::getValue));
List<Data> byValue = new ArrayList<>(theList);
System.out.println("\nSorted by value\n");
byValue.forEach(System.out::println);

the above prints

Sorted by String

[aba231, 9831]
[abc123, 9986]
[ads314, 1234]
[cat202, 9382]
[dal192, 3214]
[gog113, 1493]
[jga213, 9432]
[sam273, 9823]
[wor213, 7643]
[wos987, 1292]

Sorted by value

[ads314, 1234]
[wos987, 1292]
[gog113, 1493]
[dal192, 3214]
[wor213, 7643]
[cat202, 9382]
[jga213, 9432]
[sam273, 9823]
[aba231, 9831]
[abc123, 9986]

Here is another example sorting first by string then by int if the strings are equal.

List<Data> newList = new ArrayList<>(
        List.of(new Data("to", 10), new Data("be", 8),
                new Data("or", 12), new Data("not ", 15),
                new Data("to", 9), new Data("be", 4),
                new Data("that", 8), new Data("is", 2),
                new Data("the", 3), new Data("question", 2)));

newList.sort(Comparator.comparing(Data::getString)
        .thenComparing(Data::getValue));

System.out.println("\nSorting by String, then int.\n");
newList.forEach(System.out::println);

prints

Sorting by String, then int.

[be, 4]
[be, 8]
[is, 2]
[not , 15]
[or, 12]
[question, 2]
[that, 8]
[the, 3]
[to, 9]
[to, 10]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ryan
Solution 2 Cheng Thao
Solution 3