在Java中按y值排序坐标的最简单方法?

时间:2013-01-05 19:09:02

标签: java arrays list sorting

假设我有一个(以任何方式未排序)数组:

[ 12 64 35 ]
[ 95 89 95 ]
[ 32 54 09 ]
[ 87 56 12 ]

我想对它进行排序,以便第二列按升序排列:

[ 32 54 09 ]
[ 87 56 12 ]
[ 12 64 35 ]
[ 95 89 95 ]

以下是我考虑解决这个问题的方法:

  1. 将每个[x y z]值设为一个列表,并将每个xyz值与一个标识符相关联,该标识符的属性是xyz值的y值。然后,对标识符进行排序。 (我不确定排序Java数组是否保留该行中的相应值)

  2. 使用hashmap执行与上一个

  3. 相同的操作

    然而,上述两种方法显然有点浪费和复杂,因为它们依赖于不需要的外部标识符值,所以有更简单,更快速,更优雅的方法吗?

    很抱歉,如果这是一个愚蠢的问题,我对Java排序数组的方式一点也不熟悉。

4 个答案:

答案 0 :(得分:8)

最简单,最干净的方法是编写一个小型比较器类。这样可以更灵活地控制排序行为;例如,您可以对第一个元素或数组的任何元素进行排序。

比较器将类似于:

new Comparator(){

            public int compare ( Integer[] obj1, Integer[] obj2)
            {
                return obj1[1].compareTo(obj2[1]); 
            }

答案 1 :(得分:6)

这是一个单行(如果你将一个匿名类统计为一行),使用Arrays.sort()和一个适当的类型和编码Comparator

Arrays.sort(grid, new Comparator<int[]>() {
    public int compare(int[] o1, int[] o2) {
        return o1[1] - o2[1];
    }
});

请注意简单比较表达式o1[1] - o2[1] - 无需取消装箱到Integer并使用Integer.compareTo()

以下是您的数据测试:

public static void main(String[] args) {
    int[][] grid = new int[][] { 
        { 12, 64, 35 },
        { 95, 89, 95 },
        { 32, 54,  9 },
        { 87, 56, 12 }};
    Arrays.sort(grid, new Comparator<int[]>() {
        public int compare(int[] o1, int[] o2) {
            return o1[1] - o2[1];
        }
    });
    System.out.println(Arrays.deepToString(grid).replace("],", "],\n"));
}

输出:

[[32, 54, 9],
 [87, 56, 12],
 [12, 64, 35],
 [95, 89, 95]]



只是为了好玩,这里的字面意思是一行:

Arrays.sort(grid, new Comparator<int[]>() {public int compare(int[] o1, int[] o2) {return o1[1] - o2[1];}});

答案 2 :(得分:2)

使用自定义比较器。

此实现更通用,因为您可以将它用于任何Comparable类型和任何排序索引。如果您还需要T类型本身的自定义比较器,则需要在构造函数中传递它并替换.compareTo()调用。

public class ArrayElementComparator<T implements Comparable<? super T>> implements Comparator<T[]> {

    private final int sortIndex;

    public ArrayElementComparator(int sortIndex) {
        this.sortIndex = sortIndex;
    }

    @Override
    public int compare(T[] left, T[] right) {
        // Optional: null checks and boundary checks
        if (left == null && right == null) {
            return 0;
        }
        if (left == null || left.length <= sortIndex) {
            return 1;
        }
        if (right == null || right.length <= sortIndex) {
            return -1;
        }
        return left[sortIndex].compareTo(right[sortIndex]);
    }

}

用法:

List<Integer[]> list = new List<Integer[]>();
// ... Add records
Collections.sort(list, new ArrayElementComparator<Integer>(1));

答案 3 :(得分:1)

如果这三个值代表3D欧几里德空间中的(x,y,z)坐标,您可以编写一个类来保存它们。然后使用这些点的List或数组以及客户Comparator按照您希望的方式对它们进行排序。