ALx ALx ALx ALx - 7 months ago 17
Java Question

Print 2d String array by column

I'm doing a school project and I need to print the array by amount spent (descending). The problem is that I got nulls inside it by joining 5 arrays into one and having to gather the information inside a for loop so I had to declare the array at the top of my code.

So my code is something like this:



Entry | Amount | Category | Payment | Date

String array[][]={ {"5", "22,2", "car payment", "visa", "21/04/2016"},
{"1", "44,4", "shop", "cash", "16/02/2017"},
{"2", "33,1", "shop", "cash", "15/01/2020"},
{"3", "17,3", "gym", "visa", "10/01/2016"},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null}, };


So I tried using
Arrays.sort()
using the
Comparator
but I can't seem to get it right since I got those nulls inside I always get
java.lang.NullPointerException
.

What I tried is this:

Arrays.sort(array, (String[] o1, String[] o2) -> Float.compare(Float.parseFloat(o2[1]),
Float.parseFloat(o1[1])));


And what I'm trying to get is:

{"1", "44,4", "shop", "cash", "16/02/2017"},
{"2", "33,1", "shop", "cash", "15/01/2020"},
{"5", "22,2", "car payment", "visa", "21/04/2016"},
{"3", "17,3", "gym", "visa", "10/01/2016"}};


Any help would be so appreciated. Thank you!

Answer

I believe the following code works reasonably well:

public class StringArraySorter {
    public static void main(String[] args) {
        String array[][]={  {"5", "22,2", "car payment", "visa", "21/04/2016"},
                {"1", "44,4", "shop", "cash", "16/02/2017"},
                {"2", "33,1", "shop", "cash", "15/01/2020"},
                {"3", "17,3", "gym", "visa", "10/01/2016"},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null},
        };

        Arrays.sort(array, new Comparator<String[]>() {
            @Override
            public int compare(String[] o1, String[] o2) {
                String a1 = o1[1]; // amount field
                String a2 = o2[1]; // amount field
                if (a1 != null && a2 != null) {
                    a1 = a1.replace(',', '.');
                    a2 = a2.replace(',', '.');
                    return Float.compare(Float.parseFloat(a2), Float.parseFloat(a1));
                }
                return 1; // non-null value for amount takes precedence, whatever that may be
            }
        });
        System.out.println(Arrays.deepToString(array));
    }
}

It prints (modified to insert newlines) which is close to your requirements:

[[1, 44,4, shop, cash, 16/02/2017], 
[2, 33,1, shop, cash, 15/01/2020], 
[5, 22,2, car payment, visa, 21/04/2016], 
[3, 17,3, gym, visa, 10/01/2016], 
[null, null, null, null, null], 
[null, null, null, null, null], 
[null, null, null, null, null], 
[null, null, null, null, null]]

Now, you could always prune your input array to remove the records (string arrays) that have certain key fields null (or invalid in some other way), before sending the array to the Arrays.sort method. An initial attempt at it using Java 8 constructs would be:

    Arrays.stream(array).filter(a -> a[0] != null).sorted((o1, o2) -> {
        String a1 = o1[1];
        String a2 = o2[1];
        if (a1 != null && a2 != null) {
            a1 = a1.replace(',', '.');
            a2 = a2.replace(',', '.');
            return Float.compare(Float.parseFloat(a2), Float.parseFloat(a1));
        }
        return 1;
    }).forEach(a -> System.out.println("{" + Arrays.stream(a).map(s -> "\"" + s + "\"").collect(Collectors.joining(", ")) +
            "}"));

that prints:

{"1", "44,4", "shop", "cash", "16/02/2017"}
{"2", "33,1", "shop", "cash", "15/01/2020"}
{"5", "22,2", "car payment", "visa", "21/04/2016"}
{"3", "17,3", "gym", "visa", "10/01/2016"}