【问题标题】:Sorting multiple lists by the values of another list in java根据java中另一个列表的值对多个列表进行排序
【发布时间】:2015-08-29 13:05:22
【问题描述】:

我有 6 个 ArrayList,如下所示:

index: 0         1           2          3            4          5

[12345.12   |123.0      |12.12      |1234.0     |123.12     |123.12    ] <Double>
[2000-01-11 |2000-01-11 |2000-01-11 |2000-01-12 |2000-01-12 |2000-01-11] <String>
[1234       | 1234      | 1234      | 1235      | 1235      | 1234     ] <String>
[4          | 10        | 16        | 24        | 30        | 20       ] <Integer>
[7          | 13        | 19        | 27        | 34        | 25       ] <Integer>
[9          | 15        | 21        | 29        | 35        | 40       ] <Integer>

使用 Java,我想按第一个列表的值降序对它们进行排序如果第一个列表中的值相等,则将两个相等的值按第二个列表中的对应值按自然顺序排序。第二个列表中的字符串可以通过调用 Collection.sort(second_list) 以自然顺序排序。

(示例:因为索引 4 和 5 处的元素相等,我必须按第二个列表中索引 4 和 5 处的元素按自然顺序对它们进行排序:123.12 = 123.12 但“2000-01- 12" > "2000-01-11",所以最后两个索引的顺序是 5, 4)

排序后的列表应如下所示:

     0            3           5          4            1         2 

[12345.12   |1234.0     |123.12     |123.12     |123.0      |12.12     ] <Double>
[2000-01-11 |2000-01-12 |2000-01-11 |2000-01-12 |2000-01-11 |2000-01-11] <String>
[1234       | 1235      | 1234      | 1235      | 1234      | 1234     ] <String>
[4          | 24        | 20        | 30        | 10        | 16       ] <Integer>
[7          | 27        | 25        | 34        | 13        | 19       ] <Integer>
[9          | 29        | 40        | 35        | 15        | 21       ] <Integer>

我尝试构建一个字符串数组列表,其中列表中的每个元素都包含一列中的元素,如上所示(例如:索引为 0 的列)。在上面列中的每个元素之后,我用逗号“,”连接字符串,以便在排序后拆分字符串(例如:“12345.12,2000-01-11,...,9”。因为排序没有没有按预期工作,我放弃了这个计划。

我需要一种允许行中重复值的表。

如果第一个 List 是一个 Map,其中索引是键,值是上面 ArrayLists 中的元素,我可以这样做:

  • 我按值对Map&lt;Integer, Double&gt; 的值进行排序。 索引 - 是键,呈现的第一个列表中的元素 - 是值。所以我得到了索引的顺序:0 3 5 4 1 2
  • 我按此自定义顺序对其他 ArrayList 进行排序,但如果 Map&lt;Integer, Double&gt; 中的值重复,我该怎么办?如何按第二个 List 中元素的自然顺序对它们进行排序?

...我需要一个可以快速排序提到的列表的结构。

【问题讨论】:

  • Collections.sort 采用可选的Comparator。写一个使用主列表中的值排序的。
  • 您是否必须为要比较的每个对象创建一个列表?如果你想比较另一个,你必须手动创建另一个ArrayList?为什么不使用 OOP 范例 并使用您的数据创建一个对象,然后任何时候您想要添加一个新对象,您只需实例化一个新对象并添加到您的列表中。此外,当您想比较它们时,只需使用 nameList.get(i).getNameFirstValue()
  • 看到这个related questionthis one,和this one
  • 而不是有 6 个属性的数组列表,听起来你应该有 1 个具有 6 个属性的对象列表。那么问题将是微不足道的 - 只需使用比较器对列表进行排序,用于连续检查每个属性的对象
  • @twentymon Collections#sort 没有采取方法改变swap 的实现,这是问题的根源。比较不是问题。

标签: java sorting arraylist row


【解决方案1】:

使用您的值名称创建一个项目对象:

public class Item {

    private Double value1;

    private String value2;

    private String value3;

    private Integer value4;

    private Integer value5;

    private Integer value6;

    public Double getValue1() {
        return value1;
    }

    public void setValue1(Double value1) {
        this.value1 = value1;
    }

    public String getValue2() {
        return value2;
    }

    public void setValue2(String value2) {
        this.value2 = value2;
    }

    public String getValue3() {
        return value3;
    }

    public void setValue3(String value3) {
        this.value3 = value3;
    }

    public Integer getValue4() {
        return value4;
    }

    public void setValue4(Integer value4) {
        this.value4 = value4;
    }

    public Integer getValue5() {
        return value5;
    }

    public void setValue5(Integer value5) {
        this.value5 = value5;
    }

    public Integer getValue6() {
        return value6;
    }

    public void setValue6(Integer value6) {
        this.value6 = value6;
    }        

}

在其他类中使用这个:

public class Test {

    ArrayList<Item> items;

    public Test(){
        items = new ArrayList<>();
        this.dataList();
    }

    public void dataList(){
        Item item = new Item();
        item.setValue1(12345.12);
        item.setValue2("2000-01-11");
        // add all your values
        items.add(item);              
        // do the same for all your objects

        //Sort your list with a custom Comparator
        Collections.sort(items, new Comparator<Item>() {
            @Override
            public int compare(Item item1, Item item2) {
                return item1.getValue1().compareTo(item2.getValue1());
            }
        });        
     }
}

【讨论】:

    【解决方案2】:

    这是一种排序的粗略实现,它使用来自几个等长的独立 Comparable 列表的值来创建一个顺序,其中列表表示排序键。

    public static void sort( List<List<? extends Comparable>> lol ){
        List<Integer> index = new ArrayList<>();
        for( int i = 0; i < lol.get(0).size(); ++i ){
            index.add( i );
        }
        Collections.sort( index, new CompInd( lol, index) );
        for( int i: index ){
            for( int j = 0; j < lol.size(); ++j ){
                System.out.print( " " + lol.get(j).get(i) );
            }
            System.out.println();
        }
    }
    

    类 CompInd 为 n 个列表的 索引 实现比较器。

    class CompInd implements Comparator<Integer> {
        private List<List<? extends Comparable>> comp;
        private List<Integer> index;
        public CompInd( List<List<? extends Comparable>> comp, List<Integer> index ){
            this.comp = comp;
            this.index = index;
        }
    
        public int compare(Integer ind1, Integer ind2){
            for( int i = 0; i < comp.size(); ++i ){
                int res = 
                    comp.get(i).get(ind1).compareTo( comp.get(i).get(ind2) );
                if( res != 0 ) return res;
            }
            return 0;
        }
    }
    

    main 方法(根据您的数据)创建三个列表并调用排序。

    public static void main( String[] args ){
        List<Double> dl1 = new ArrayList<>();
        for( double d: new double[]{12345.12, 123.0, 12.12, 1234.0, 123.12, 123.12} ){
            dl1.add( d );
        }
        List<String> sl1 = new ArrayList<>();
        for( String s: new String[]{"2000-01-11","2000-01-11","2000-01-11","2000-01-12","2000-01-12","2000-01-11"} ){
            sl1.add( s );
        }
        List<String> sl2 = new ArrayList<>();
        for( String s: new String[]{"1234","1234","1234","1235","1235","1234"} ){
            sl2.add( s );
        }
    
        List<List<? extends Comparable>> lol = new ArrayList<>();
        lol.add( dl1 );
        lol.add( sl1 );
        lol.add( sl2 );
        sort( lol );
        }
    }
    

    这适用于任意数量的并行列表,当然前提是它们都是实现 Comparable 的对象列表。

    【讨论】:

    • 感谢您的帮助。我没有尝试你的例子,因为我没有时间。我亲自解决了这个问题,但我现在太忙了,无法描述解决方案。我会尝试你的例子,如果它们比我的解决方案更好,我会接受你的答案,或者我会告诉你它是否有效。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 2018-11-15
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多