簡體   English   中英

根據一列對二維數組進行排序

[英]Sort a two dimensional array based on one column

在 Java 中,我的數組中有如下數據

2009.07.25 20:24 Message A
2009.07.25 20:17 Message G
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 20:01 Message F
2009.07.25 21:08 Message E
2009.07.25 19:54 Message R

我想根據第一列對其進行排序,所以我的最終數據看起來像這樣

2009.07.25 19:54 Message R
2009.07.25 20:01 Message F
2009.07.25 20:17 Message G
2009.07.25 20:24 Message A
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 21:08 Message E

第一列是格式為“yyyy.MM.dd HH:mm”的日期,第二列是字符串。

根據一列對二維數組進行排序
第一列是格式為“yyyy.MM.dd HH:mm”的日期,第二列是字符串。

既然你說的是二維數組,我假設“格式日期……”是指一個字符串。 下面是對 String[][] 的二維數組進行排序的代碼:

import java.util.Arrays;
import java.util.Comparator;

public class Asdf {

    public static void main(final String[] args) {
        final String[][] data = new String[][] {
                new String[] { "2009.07.25 20:24", "Message A" },
                new String[] { "2009.07.25 20:17", "Message G" },
                new String[] { "2009.07.25 20:25", "Message B" },
                new String[] { "2009.07.25 20:30", "Message D" },
                new String[] { "2009.07.25 20:01", "Message F" },
                new String[] { "2009.07.25 21:08", "Message E" },
                new String[] { "2009.07.25 19:54", "Message R" } };

        Arrays.sort(data, new Comparator<String[]>() {
            @Override
            public int compare(final String[] entry1, final String[] entry2) {
                final String time1 = entry1[0];
                final String time2 = entry2[0];
                return time1.compareTo(time2);
            }
        });

        for (final String[] s : data) {
            System.out.println(s[0] + " " + s[1]);
        }
    }

}

輸出:

2009.07.25 19:54 Message R
2009.07.25 20:01 Message F
2009.07.25 20:17 Message G
2009.07.25 20:24 Message A
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 21:08 Message E
class ArrayComparator implements Comparator<Comparable[]> {
    private final int columnToSort;
    private final boolean ascending;

    public ArrayComparator(int columnToSort, boolean ascending) {
        this.columnToSort = columnToSort;
        this.ascending = ascending;
    }

    public int compare(Comparable[] c1, Comparable[] c2) {
        int cmp = c1[columnToSort].compareTo(c2[columnToSort]);
        return ascending ? cmp : -cmp;
    }
}

這樣您就可以處理這些數組中的任何類型的數據(只要它們是可比較的)並且您可以按升序或降序對任何列進行排序。

String[][] data = getData();
Arrays.sort(data, new ArrayComparator(0, true));

PS:確保檢查ArrayIndexOutOfBounds和其他。

編輯:只有當您能夠在第一列中實際存儲java.util.Date或者您的日期格式允許您對這些值使用純字符串比較時,上述解決方案才會有用。 否則,您需要將該字符串轉換為日期,您可以使用回調接口(作為通用解決方案)來實現。 這是一個增強版本:

class ArrayComparator implements Comparator<Object[]> {
    private static Converter DEFAULT_CONVERTER = new Converter() {
        @Override
        public Comparable convert(Object o) {
            // simply assume the object is Comparable
            return (Comparable) o;
        }
    };
    private final int columnToSort;
    private final boolean ascending;
    private final Converter converter;


    public ArrayComparator(int columnToSort, boolean ascending) {
        this(columnToSort, ascending, DEFAULT_CONVERTER);
    }

    public ArrayComparator(int columnToSort, boolean ascending, Converter converter) {
        this.columnToSort = columnToSort;
        this.ascending = ascending;
        this.converter = converter;
    }

    public int compare(Object[] o1, Object[] o2) {
        Comparable c1 = converter.convert(o1[columnToSort]);
        Comparable c2 = converter.convert(o2[columnToSort]);
        int cmp = c1.compareTo(c2);
        return ascending ? cmp : -cmp;
    }

}

interface Converter {
    Comparable convert(Object o);
}

class DateConverter implements Converter {
    private static final DateFormat df = new SimpleDateFormat("yyyy.MM.dd hh:mm");

    @Override
    public Comparable convert(Object o) {
        try {
            return df.parse(o.toString());
        } catch (ParseException e) {
            throw new IllegalArgumentException(e);
        }
    }
}

此時,您可以對第一列進行排序:

Arrays.sort(data, new ArrayComparator(0, true, new DateConverter());

我跳過了空值檢查和其他錯誤處理問題。

我同意這已經開始看起來像一個框架了。 :)

最后(希望)編輯:我現在才意識到您的日期格式允許您使用純字符串比較。 如果是這種情況,則不需要“增強版”。

Arrays.sort(yourarray, new Comparator() {
    public int compare(Object o1, Object o2) {
        String[] elt1 = (String[])o1;
        String[] elt2 = (String[])o2;
        return elt1[0].compareTo(elt2[0]);
    }
});
  1. 安裝java8 jdk+jre

  2. 使用lamda 表達式二維數組進行排序。

代碼:

import java.util.Arrays;
import java.util.Comparator;

class SortString {

    public static void main(final String[] args) {
        final String[][] data = new String[][] {
                new String[] { "2009.07.25 20:24", "Message A" },
                new String[] { "2009.07.25 20:17", "Message G" },
                new String[] { "2009.07.25 20:25", "Message B" },
                new String[] { "2009.07.25 20:30", "Message D" },
                new String[] { "2009.07.25 20:01", "Message F" },
                new String[] { "2009.07.25 21:08", "Message E" },
                new String[] { "2009.07.25 19:54", "Message R" } 
        };
        // this is applicable only in java 8 version.
        Arrays.sort(data, (String[] s1, String[] s2) -> s1[0].compareTo(s2[0]));

        // we can also use Comparator.comparing and point to Comparable value we want to use        
        // Arrays.sort(data, Comparator.comparing(row->row[0]));

        for (final String[] s : data) {
            System.out.println(s[0] + " " + s[1]);
        }
    }
}

輸出

2009.07.25 19:54 Message R
2009.07.25 20:01 Message F
2009.07.25 20:17 Message G
2009.07.25 20:24 Message A
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 21:08 Message E

假設您的數組包含字符串,您可以使用以下內容:

String[] data = new String[] { 
    "2009.07.25 20:24 Message A",
    "2009.07.25 20:17 Message G",
    "2009.07.25 20:25 Message B",
    "2009.07.25 20:30 Message D",
    "2009.07.25 20:01 Message F",
    "2009.07.25 21:08 Message E",
    "2009.07.25 19:54 Message R"
};

Arrays.sort(data, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        String t1 = s1.substring(0, 16); // date/time of s1
        String t2 = s2.substring(0, 16); // date/time of s2
        return t1.compareTo(t2);
    }
});

如果你有一個二維數組,解決方案也非常相似:

String[][] data = new String[][] { 
        { "2009.07.25 20:17", "Message G" },
        { "2009.07.25 20:25", "Message B" },
        { "2009.07.25 20:30", "Message D" },
        { "2009.07.25 20:01", "Message F" },
        { "2009.07.25 21:08", "Message E" },
        { "2009.07.25 19:54", "Message R" }
};

Arrays.sort(data, new Comparator<String[]>() {
    @Override
    public int compare(String[] s1, String[] s2) {
        String t1 = s1[0];
        String t2 = s2[0];
        return t1.compareTo(t2);
    }
});

從 Java 8 開始使用 Lambda:

final String[][] data = new String[][] { new String[] { "2009.07.25 20:24", "Message A" },
        new String[] { "2009.07.25 20:17", "Message G" }, new String[] { "2009.07.25 20:25", "Message B" },
        new String[] { "2009.07.25 20:30", "Message D" }, new String[] { "2009.07.25 20:01", "Message F" },
        new String[] { "2009.07.25 21:08", "Message E" }, new String[] { "2009.07.25 19:54", "Message R" } };
String[][] out = Arrays.stream(data).sorted(Comparator.comparing(x -> x[1])).toArray(String[][]::new);

System.out.println(Arrays.deepToString(out));
    

輸出:

[[2009.07.25 20:24, 消息A], [2009.07.25 20:25, 消息B], [2009.07.25 20:30, 消息D], [2009.07.25 21:08, 消息E], [ 2009.07.25 20:01, 消息F], [2009.07.25 20:17, 消息G], [2009.07.25 19:54, 消息R]]

查看ColumnComparator 它與 Costi 提出的解決方案基本相同,但它還支持對 List 中的列進行排序,並且具有更多的排序屬性。

如果您正在尋找簡單的一行來對 2d 數組進行排序,那么就來這里吧。


按第一列升序排序 String[][] arr

Arrays.sort(arr, (a, b) -> a[0].compareTo(b[0]);

按第一列降序排列 String[][] arr

Arrays.sort(arr, (a, b) -> b[0].compareTo(a[0]);

按第二列升序排序 String[][] arr

Arrays.sort(arr, (a, b) -> a[1].compareTo(b[1]);

按第二列降序排列 String[][] arr

Arrays.sort(arr, (a, b) -> b[1].compareTo(a[1]);

按第一列升序排序 int[][] arr

Arrays.sort(arr, (a, b) -> Integer.compare(a[0], b[0]));

要么

Arrays.sort(arr, (a, b) -> a[0] - b[0]);

按第一列降序排列 int[][] arr

Arrays.sort(arr, (a, b) -> Integer.compare(b[0], a[0]));

要么

Arrays.sort(arr, (a, b) -> b[0] - a[0]);

按第二列升序排序 int[][] arr

Arrays.sort(arr, (a, b) -> Integer.compare(a[1], b[1]));

要么

Arrays.sort(arr, (a, b) -> a[1] - b[1]);

按第二列降序排列 int[][] arr

Arrays.sort(arr, (a, b) -> Integer.compare(b[1], a[1]));

要么

Arrays.sort(arr, (a, b) -> b[1] - a[1]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM