【问题标题】:Java: sort a list of listsJava:对列表进行排序
【发布时间】:2013-07-09 12:23:02
【问题描述】:

我有一个点列表,即:List<List<Point>>。 例如:

List<Point> lp;
List<List<Point>> Llp;
Llp.add(lp);

lp将是我矩阵的第一行 (x=0)。 Llp是整个矩阵。

我想根据每个点的 x 和 y 对列表进行升序排序。我只设法对内部列表进行了排序,而不是对整个列表进行了排序。任何人都可以帮助我吗?谢谢你。这是我根据 y 对内部列表(即矩阵的第一行)进行排序的代码。

private void ord_horiz (List<Point> tab)
{
    boolean ordered_horiz = false;
    int size = tab.size();

    while(!ordered_horiz)
    {
        ordered_horiz = true;

        for(int i=0 ; i < size-1 ; i++)
        {
            if(tab.get(i).y > tab.get(i+1).y)
            {
                swap(tab, i, i+1);
                ordered_horiz = false;
            }
        }
        size--;
    }   
}

private void swap(List<Point> tab, int ind1, int ind2) 
{
    Point c;
    c = tab.get(ind1); 
    tab.set(ind1, tab.get(ind2));
    tab.set(ind2, c);
}

这是我目前写的代码:

Collections.sort(tab,new Comparator<List<Point>>(){


        @Override
        public int compare(List<Point> o1, List<Point> o2) {
            if(o1 != null && o2 !=null)
            {
                Point var1 = o1.get(0);
                            int var1_x = var1.x;
                            int var1_y = var1.y;
                Point var2 = o2.get(0);
                            int var2_x = var2.x;
                            int var2_y = var2.y;

                            Integer.compare(var1_x, var2_x);
                            Integer.compare(var1_y, var2_y);
                return /* What shall I return ? */;                 
            }
            return 0;
        }
    });

这是我的控制台输出的屏幕截图。我希望对这一点进行排序。 http://imageshack.us/scaled/large/515/38zy.png

【问题讨论】:

  • 你考虑过使用Collections.sort(...)吗?
  • 你试过用Collections.sort()吗?
  • Collections.sort() 仅对一维列表进行排序。我的清单做不到。
  • 您能否详细说明您想要排序的内容?列表列表应该如何排序?对我来说,这还不清楚。
  • 您希望如何对外部列表进行排序?

标签: java list sorting collections point


【解决方案1】:

"我想根据 x 和 y 对外部列表进行排序,假设 x 是 Llp 和 y 中 lp 的顺序是每个元素的顺序 LLP 中的 LLP。”

您应该使用自定义比较器。由于我假设 LLP 中的每个列表都具有相同数量的元素,并且每个列表仅用于不同的 X,因此以下应该有效:

示例

//Create the Data

    List<List<Point>> Llp = new ArrayList<List<Point>>();

    for(int i=0; i< 50; i++)
    {
        List<Point> lp = new ArrayList<Point>();

        for(int j=0; j<50; j++)
        lp.add(new Point((int)(Math.random()*1000), i));

        Llp.add(lp);
    }



    // The comparators
    Comparator<List<Point>> comparator_rows = new Comparator<List<Point>>() {

        @Override
        public int compare(List<Point> o1, List<Point> o2) {
            int i = o2.get(0).y;
            int j = o1.get(0).y;
            if (i < j) {
                return 1;
            } else if (i > j) {
                return -1;
            } else {
                return 0;
            }
        }

    };

    Comparator<Point> comparator_columns = new Comparator<Point>() {

        @Override
        public int compare(Point o1, Point o2) {
            int i = o2.x;
            int j = o1.x;
            if (i < j) {
                return 1;
            } else if (i > j) {
                return -1;
            } else {
                return 0;
            }
        }

    };

    // Sort the rows
    Collections.sort(Llp, comparator_rows);

    // Sort the columns
    for (List<Point> element : Llp) 
        Collections.sort(element, comparator_columns);

    //Print the elements
    int rowIndex = 0, columnIndex=0;

    for (List<Point> row : Llp) 
    {
        for (Point element : row) 
        System.out.print("("+element.x+ "," + element.y +")|");

        System.out.println();
    }

以上代码获取每一行的第一个元素,并提取X坐标。然后这个 x 坐标用于对所有行进行排序。

更新

如果您的数据全部混淆,您可以使用以下代码,该代码使用 TreeMaps 将您的元素放置在它们应该在的位置。结果是一个锯齿状数组。

//Create the Data

        List<List<Point>> Llp = new ArrayList<List<Point>>();

        for(int i=0; i< 50; i++)
        {
            List<Point> lp = new ArrayList<Point>();

            for(int j=0; j<50; j++)
            lp.add(new Point((int)(Math.random()*1000), (int)(Math.random()*1000)));

            Llp.add(lp);
        }


        //If all data is mixed up we need to filter into new rows based on X using a TreeMap

        TreeMap<Integer, TreeMap<Integer,Point>> data = new TreeMap<Integer,TreeMap<Integer,Point>>();

        for (List<Point> row : Llp) 
        {
            for (Point element : row) 
            {
                TreeMap<Integer,Point> rowForX;
                if(data.containsKey(element.x))
                    rowForX = data.get(element.x);
                else
                    data.put(element.x, rowForX = new TreeMap<Integer,Point>());    
                    //Create specific row in TreeMap

                rowForX.put(element.y,element);
            }           
        }


        //Convert Sorted TreeMap(s) to Lists

        Llp.clear();
        Iterator<Entry<Integer, TreeMap<Integer, Point>>> it = data.entrySet().iterator();

        while(it.hasNext())
            Llp.add(new ArrayList<Point>(it.next().getValue().values()));


        //Print the elements
        int rowIndex = 0, columnIndex=0;

        for (List<Point> row : Llp) 
        {
            for (Point element : row) 
            System.out.print("("+element.x+ "," + element.y +")|");

            System.out.println();
        }

【讨论】:

  • 哦,非常感谢。我想这就是我要找的:)
  • 对不起,我还有一个问题,有没有办法让这个比较器同时比较 x 和 y?
  • 当然,只需在当前显示return 0; 的地方添加一个内部if 语句
  • 比较器主要用于比较列表中的元素。由于列表中有列表,因此您需要对外部列表进行一种排序,并对列表中的每个列表进行另一种排序。我已经更新了我的代码。问题是,您的积分是否已经分组为 Y 行,还是所有数据都混在一起了?
  • @meewoK 所有数据都混在一起了。我唯一拥有的是每个点都用它的 x 和 y 坐标定义。我会将控制台的屏幕截图添加到我的问题中,以便更清晰。
猜你喜欢
  • 2018-10-20
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多