2011-02-05 145 views
40

在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」,第二列是一個字符串。

回答

70

排序的二維陣列基於一個柱
第一列是格式「YYYY.MM.DD HH:MM」的日期和第2欄是一個字符串。

既然你說二維數組,我認爲「格式日期...」意味着一個字符串。這裏的代碼進行排序字符串[] []的2-d數組:

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 
8
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]); 
    } 
}); 
+2

-1這韓元不會編譯。應該排序(數組,比較器)。 – dogbane 2011-02-05 15:44:43

+3

根據@ dogbane的修正編輯。 – 2011-02-05 16:18:23

5

假設你的數組包含字符串,可以使用以下命令:

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); 
    } 
}); 
+0

-1 OP表示它是一個二維數組。 – dogbane 2011-02-05 16:01:56

+0

@dogbane看看這個問題。它不*實際上是一個二維數組,即使標題堅持它是。它是一個內部有柱狀數據的`String`數組。事實上,這個迴應比其他所有人都更好地解決了實際問題...... – dkarp 2011-02-05 16:15:06

11
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; 
    } 
} 

這樣你就可以處理這些數組中的任何類型的數據(只要它們是Comparable),並且你可以對asc中的任何列進行排序結束或降序。

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

PS:確保您檢查了ArrayIndexOutOfBounds等。

編輯:如果你能實際上是java.util.Date存儲在第一列或者如果你的日期格式允許你使用普通的字符串比較這些值上述解決方案只能是有益的。否則,您需要將該String轉換爲日期,並且可以使用回調接口(作爲常規解決方案)來實現。下面是一個加強版:

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()); 

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

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

最後(希望)編輯:我現在只知道你的日期格式允許你使用普通的字符串比較。如果是這種情況,則不需要「增強版」。

3

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

4
  1. 安裝java8 JDK + JRE

  2. 使用的λ表達二維數組進行排序。

代碼:

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 
2

使用Lambda表達式由於Java 8:

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]]