user3472897
user3472897

Reputation: 250

Sort 2D Array in Java based by Row

I have an 2D String[][] array like this:

Date     Product1    Product2     Product3
01/01    10          50           100
02/01    10          50           100
03/04    10          50           100
Sum      30          150          300

and I want to sort it by the Sum row ascending. The final result should be:

Date     Product3    Product2     Product1
01/01    100         50           10
02/01    100         50           10
03/04    100         50           10
Sum      300         150          30

I can order it with Arrays.sort per line, but how to do it efficiently by row?

Upvotes: 0

Views: 321

Answers (2)

Vivin Paliath
Vivin Paliath

Reputation: 95588

A 2-D string array is probably not the best representation for this. It's going to be difficult for you to manipulate the data. I would encapsulate the product and date information inside its own object:

public class ProductDateInformation { //Use a better name - this is just a placeholder because I'm not sure what it is you're describing
    private String productName;
    private Date date;
    private int amount;

    ...
}

Then you can maintain a List<ProductDateInformation> productList. From here you can group by productName and just sum up amount, and then sort by it as well. This uses Java 8's streaming API:

Map<String, Integer> sorted = productList
            .stream()
            .collect(
                Collectors.groupingBy(ProductDateInformation::getProductName),
                Collectors.summingInt(ProductDateInformation::getAmount)
            ).entrySet().stream()
            .sorted(Map.Entry.comparingByValue())
            .collect(Collectors.toMap(
                Entry::getKey, 
                Entry::getValue,
                (value1, value2) -> value1,
                LinkedHashMap::new
            ));

So what's happening here is the following:

  • stream() just creates a "stream" out a list. This gives you access to the Stream API which gives you a bunch of methods related to transformation, collection, reduction, aggregation, etc.
  • collect(...) collects the results into some kind of object. Here we're creating a map by grouping on productName (so all instances with the same product name will be grouped together) and then we sum based on amount. This is essentially calculating the same information you have in the last row of your 2-D array. This information is returned in a map where the key is the product name, and the value is the sum of all the amounts for that particular product name.
  • entrySet().stream() streams the items in the entry set. The entry set is a set of all the entries in a map. Recall that we collected the information into a map, and now we want to sort it. So we need to look at each entry in the map. So we will access the entry set and create a new stream out of it.
  • sorted() means that we want to sort the items in the stream in some manner. Here we are passing in a comparator that says that we want to sort by the value of a map entry (i.e., the sum of the amounts).
  • .collect(...) in this call to collect, we are simply collecting the information into a new map. This map will also be keyed by product name, but will be sorted based on the amount sum. We are specifically telling it to create a new map using the LinkedHashMap variant so that we can preserve order.

Upvotes: 0

Pshemo
Pshemo

Reputation: 124275

You can always create new temporary array (or List) of objects which can store value of sum and columnId. Then order this array using sum.
This way new order of columnId will show you how your original array should be sorted.

Upvotes: 1

Related Questions