简体   繁体   中英

How to sort a multidimensional array in order of appearance in Java?

If the title isn't clear, let me give you an example:

I've got an array sorted by first column - date and I need to sort it once again in order of appearance of value in column name

data[100][4]

date | name | text | type
-----+------+------+------
2222 | z    | wwww | 2
2221 | z    | qqqq | 1
2220 | c    | dasa | 2
2219 | b    | dsad | 1
2218 | z    | dfsa | 2
2217 | c    | dasd | 1

And here's the sorted array:

order[100][4]

date | name | text | type
-----+------+------+------
2222 | z    | wwww | 2
2221 | z    | qqqq | 1
2218 | z    | dfsa | 2
2220 | c    | dasa | 2
2217 | c    | dasd | 1
2219 | b    | dsad | 1

I thought of merging those data into one string and inserting some symbol between columns to retrieve it back in the future, adding to ArrayList and then retrieving by name. I've added data[i][1] to HashMap to determine number of unique values, so I could know the number of loop cycles. And there comes the order of name values which puzzles me because HashMap doesn't maintain order.

Does anyone know how it can be sorted without all that trouble?

Have an object representing a data entry with a date, name, text, and type, and have it implement the Comparable interface. The Comparable interface effectively allows inequality operations to be performed on the objects, and is what the Java API uses to do any sort of comparison of objects (which is used for sorting). Then to sort the data according to the given field, include a static variable in the data object class that represents which field to sort on.

class Data implements Comparable<Data>
{
    int date;     // field 1
    String name;  // field 2
    String text;  // field 3
    int type;     // field 4

    static int sortField;
    static final int DATE = 1;
    static final int NAME = 2;
    static final int TEXT = 3;
    static final int TYPE = 4;

    // put constructor here

    //compareTo function for sorting
    public int compareTo(Data other)
    {
        if (sortField == DATE)
        {
            if (date < other.date)    return -1;
            if (date > other.date)    return 1;
            else                      return 0;
        }
        if (sortField == NAME)
        {
            return name.compareTo(other.name);
        }
        if (sortField == TEXT)
        {
            return text.compareTo(other.text);
        }
        else
        {
            if (type < other.type)    return -1;
            if (type > other.type)    return 1;
            else                      return 0;
        }
    }
}

Then all you have to do is put the objects into an ArrayList and sort them

ArrayList<Data> list = new ArrayList<Data>();

//put Data objects into list here

//to sort
Data.sortField = Data.DATE;   //sort by date - change as needed
Collections.sort(list);

I've used @Aderis idea of creating a class but sorting method is slightly different. A code to initialise an array was posted here but someone deleted it. Anyway, I also used it.

String[][] myArr = { { "2222", "b", "dfsa", "2" },
                { "2221", "z", "wwww", "2" }, { "2220", "c", "qqqq", "1" },
                { "2219", "z", "dasa", "2" }, { "2218", "b", "dsad", "1" } };

HashMap<String,String> hashData = new HashMap<>();

for (int i = 0; i < myArr.length; i++) hashData.put(myArr[i][1],myArr[i][1]);
int unique_entries = hashData.size();

ArrayList<Data> list = new ArrayList<Data>();
ArrayList<Data> list_sorted = new ArrayList<Data>();

for (int i = 0; i < myArr.length; i++){
    Data temp = new Data(myArr[i][0],myArr[i][1],myArr[i][2],Integer.parseInt(myArr[i][3]));
    list.add(temp);
}

for (int k = 0; k < unique_entries; k++){
    boolean flag = true;
    ArrayList<Integer> elements = new ArrayList<>();
    int list_elements = list.size(); 
    for (int i = 0; i < list_elements; i++){
        if (flag){
            list_sorted.add(list.get(i));
            elements.add(i);
            flag = false;
            continue;
        }
        int list_sorted_elements = list_sorted.size(); 
        for (int j = 0; j < list_sorted_elements; j++){
            if (list_sorted.get(j).name.contains(list.get(i).name)){
                list_sorted.add(list.get(i));
                elements.add(i);
                break;
            }
        }
    }
    for (int i = 0; i < elements.size(); i++){ 
        int temp = elements.get(i);
        if (i != 0) temp = temp - i;
        list.remove(temp);
    }
}

As you can see, to establish the number of unique elements I add them to HashMap and check its size. I fill an ArrayList with objects of my data and add sorted data to another ArrayList , then I delete those data from unsorted List and begin to sort the rest. There are as many cycles as unique names.

I don't believe this is an optimal way. But it's the only way I know. If anyone knows faster way I'll accept their post.

Convert this 2d array into a HashMap. Object part will hold that particular array element.

Get keyset .. convert keyset into list.. sort this list.. iterate over list and get their respective array element from map.

eg code:

        String[][] myArr = new String[4][3];
        for (int i=0; i<myArr.length; i++) {
            myArr[i][0] = (i+1)+"1";
            myArr[i][1] = (i+1)+"2";
            myArr[i][2] = (i+1)+"3";
        }

        Map<String, Object> map = new HashMap<String, Object>();
        for (int i=myArr.length-1; i>=0; i--) {
            map.put(myArr[i][0], myArr[i]);
        }

        List<String> keyList = new ArrayList<String>(map.keySet());

        Collections.sort(keyList);

        String[][] myNewArray = new String[4][3];
        int a =0;
        for (String s : keyList) {
            myNewArray[a++] = ((String[])map.get(s));
        }

I am using String, in your case it is date. Even if it is something else, you can use comparable or compactor to sort that keylist.

Use your sort key as the key in map.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM