Reputation: 250
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
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
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