0

Ok, so I just now figured out how to sort a 2d array via string and integers, however I am not sure how to do combine them.

I have a 2d array of users, each row has one users data. The data is string or integer respectively down the column so if I have multiple compare methods, such as sort by name or sort by phone number, how can I implement the initial 2d array since if I declare it as a String I can no longer compare by integer, and if i declare it as an integer I can no longer compare via String.

I am using the basic 2d sort method as of now.

    final Integer[][] data1 = userlistcopy;
    Arrays.sort(data1, new Comparator<Integer[]>() {

        @Override
        public int compare(final Integer[] entry1, final Integer[] entry2) {
            final Integer time1 = entry1[1];
            final Integer time2 = entry2[1];
            return time2.compareTo(time1);
        }
    });
    System.out.println("====");
    for (final Integer[] s : data1) {
        System.out.println(s[0] + " " + s[1]);
    }

or

final String[][] data1 = userlistcopy;
        Arrays.sort(data1, new Comparator<String[]>() {

            @Override
            public int compare(final String[] entry1, final String[] entry2) {
                final String time1 = entry1[3];
                final String time2 = entry2[3];
                return time2.compareTo(time1);
            }
        });
        System.out.println("====");
        for (final String[] s : data1) {
            System.out.println(s[0] + " " + s[1]);
        }

So I is there any way to cast the variables if I am comparing a different variable type without making the compiler dislike me? Or is it possible for me to just declare the whole compareTo method an Integer (even with Strings involved) when I am only comparing the integer columns of the array?

Thanks!

EDIT, more detail: I have a 2D array, I.E.

[0][bob] [3][joe] [4][john] [6][jimmy]

It is stored in a String[][] userlistcopy; If I want to compareTo with String, it will work since I can compare userlistcopy[1] and ints can be seen as strings even though they are ignored. However, if I want to compare via Integer, I have to change userlistcopy to an Integer array, and then it freaks out since they're are Strings present, and i ignore the error it nulls out the String data slots.

EDIT (FIGURED IT OUT).

Ok, I figured it out! I just transferred all the data into an Object array, as I did so I declared their respective String/Int types, then I compared to via Object, and during the actual comparison I just casted/parsed it to my own needs, such as..

Arrays.sort(data1, new Comparator<Object[]>() {

        @Override
        public int compare(final Object[] entry1, final Object[] entry2) {
            final Integer time1 = Integer.parseInt(entry1[1].toString());
            final Integer time2 = Integer.parseInt(entry2[1].toString());
            return time2.compareTo(time1);
        }
    });

or

final Object[][] data1 = datanew;
    Arrays.sort(data1, new Comparator<Object[]>() {

        @Override
        public int compare(final Object[] entry1, final Object[] entry2) {
            final String time1 = entry1[2].toString();
            final String time2 = entry2[2].toString();
            return time2.compareTo(time1);
        }
    });

Thanks for the help though!

Windle
  • 1,385
  • 2
  • 14
  • 33
Austin
  • 3,010
  • 23
  • 62
  • 97
  • 1
    I am not too sure what you are doing, but I am fairly sure you want a 1D array of type 'User'. 'User' will be a class you define. Then to sort it, you need tell the sort function how to compare two instances of 'User', such as via surname then first name, or by phone number – thecoshman Mar 21 '12 at 13:41
  • @thecoshman I have a 2D array, I.E. [0][bob] [3][joe] [4][john] [6][jimmy] It is stored in a String[][] userlistcopy; If I want to compareTo with String, it will work since I can compare userlistcopy[1] and ints can be seen as strings even though they are ignored. However, if I want to compare via Integer, I have to change userlistcopy to an Integer array, and then it freaks out since they're are Strings present, and i ignore the error it nulls out the String data slots. – Austin Mar 21 '12 at 13:50
  • @Austin I guess this is homework and the restriction you have is to use different arrays to store ID and Name of the user, right? – Luiggi Mendoza Mar 21 '12 at 13:57
  • @LuiggiiMendoza Kind of, but we could do it however we wanted too and this is only one part of it. But I got it now, if you see my edit! :) – Austin Mar 21 '12 at 14:11
  • @Austin if you have an answer, post it as an answer and then mark it :) – Luiggi Mendoza Mar 21 '12 at 14:14
  • @Austin if it really is a homework, you should add the appropriate tag for it - `homework`. – Stefan Marinov Mar 21 '12 at 14:17
  • @Austin If you are going with the custom Comparators (which is fine), make them their own classes rather than defining them inline. That way if you ever have to sort the list by phone number somewhere else in your code, you don't have to copy the logic. It would just be something like `Arrays.sort(data1, new PhoneNumberComparator());` – Windle Mar 21 '12 at 14:40
  • @Windle it is only used once so it is in its own method activated by the actionlisteners from the GUI. -@LuiggiMendoza I can't accept my own answer for like 5 hours or something it said. :S I was able to make a date compare too! :D – Austin Mar 21 '12 at 16:03

2 Answers2

2

Fairly sure you do not need/want a 2D array. You want an 1D array of type 'User'

class User{
    public int ID;
    public String name;
}

Then make use of the custom comparator like you have already sorted for you arrays.

thecoshman
  • 8,394
  • 8
  • 55
  • 77
  • Well, all the data in the array needs to line up (thus a 2d array). Each array has 8 values (columns) per user and I need to sort by 5 differents of those column types. – Austin Mar 21 '12 at 13:56
  • 3
    A '2D array' is not to make things line up. If each user has '8 values' just add those to your 'user' class. Then you just need to make a sort algorithm that can look at different values of 'User' to compare them – thecoshman Mar 21 '12 at 14:00
  • +1. Additionally, your code will be easier to understand for others as well as you in, let's say, two or three months from now if you need to look at it, modify it and/or debug it. – Stefan Marinov Mar 21 '12 at 14:16
  • Deleted my answer and going back to yours =). You were right that Comparable probably isn't the best and he should implement custom comparators for each field. – Windle Mar 21 '12 at 14:16
  • @Windle Shame, I thought your answer had some good info, thought true it was not exactly what the OP wanted. I would provide info on this, but I don't think I have ever done custom comparators for objects in this way, in any language... – thecoshman Mar 21 '12 at 14:20
  • @thecoshman Thanks. I haven't used comparators for this before either, but I think if you swapped out the arrays for your class, and then had made a comparator for each field it could work well. Adding a comment to the question about it too. – Windle Mar 21 '12 at 14:37
1

Integer solution:

Arrays.sort(data1, new Comparator<Object[]>() {

            @Override
            public int compare(final Object[] entry1, final Object[] entry2) {
                final Integer time1 = Integer.parseInt(entry1[1].toString());
                final Integer time2 = Integer.parseInt(entry2[1].toString());
                return time2.compareTo(time1);
            }
        });

or String

final Object[][] data1 = datanew;
    Arrays.sort(data1, new Comparator<Object[]>() {

        @Override
        public int compare(final Object[] entry1, final Object[] entry2) {
            final String time1 = entry1[2].toString();
            final String time2 = entry2[2].toString();
            return time2.compareTo(time1);
        }
    });

or Date

public int compare(final Object[] entry1, final Object[] entry2) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
                time1 = sdf.parse(entry1[3].toString());
                time2 = sdf.parse(entry2[3].toString());

                return time2.compareTo(time1);
            } catch (ParseException ex) {
                ex.printStackTrace();
            }

        }
    });

I can compare them separately by making the whole 2d array an Object, then comparing them separately within the Object compareTO method. :)

Austin
  • 3,010
  • 23
  • 62
  • 97