2011-02-05 237 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]]