【问题标题】:sort list in list with comparator使用比较器对列表中的列表进行排序
【发布时间】:2016-09-06 23:35:36
【问题描述】:

我想在 Java 8 中使用比较器制作一种特定类型的流。

我有 2 节课是这样的:

public class A {
    private String mName;
    private List<B> mBObjects;

    public A(String name) {
        mBObjects = new ArrayList<>();
        mName = name;
    }

    public void addValue(B b) {
        mBObjects.add(b);
    }

    public List<B> getBObjects() {
        return mBObjects;
    }

    public String getName() {
        return mName;
    }
}

public class B {
    private int mValue;

    public B(int value) {
        mValue = value;
    }

    public int getValue() {
        return mValue;
    }
}

我用这个代码初始化论文列表:

List<A> listOfA = new ArrayList<>();

//A 1
A a = new A("a1");
a.addValue(new B(20));
a.addValue(new B(12));
listOfA.add(a);

//A 2
a = new A("a2");
a.addValue(new B(3));
listOfA.add(a);


//A 3
a = new A("a1");
a.addValue(new B(2));
a.addValue(new B(26));
a.addValue(new B(6));
listOfA.add(a);

现在我用这段代码打印列表:

for(A a: listOfA) {
        System.out.print("A: "+a.getName());
        List<B> listOfB = a.getBObjects();
        for(B b:listOfB) {
            System.out.print(" ; notes: "+b.getValue());
        }
        System.out.println(" ");
    }

结果是:

A: a1 ; value: 20 ; value: 12 
A: a2 ; value: 3 
A: a1 ; value: 2 ; value: 26 ; value: 6

我在后面加上这段代码:

listOfA = listOfA.stream().sorted(Comparator.comparing(A::getName)).collect(Collectors.toList());

这个列表的新结果是:

A: a1 ; value: 20 ; value: 12 
A: a1 ; value: 2 ; value: 26 ; value: 6 
A: a2 ; value: 3

对于每个 A 对象,我想对列表 mBObjects 进行排序而不进行 foreach 以获得此结果:

A: a1 ; value: 12 ; value: 20 
A: a1 ; value: 2 ; value: 6 ; value: 26 
A: a2 ; value: 3

谢谢!

【问题讨论】:

  • 不清楚你想做什么。为什么要避免 for each?

标签: java java-8 comparator


【解决方案1】:

如果您想要一个改变原始List 的排序,请使用List#sort 以避免创建新列表的所有开销。之后,您可以在每个mBObjects 上调用List#sort

listOfA.sort(Comparator.comparing(A::getName));
listOfA.forEach(a -> a.getBObjects().sort(Comparator.comparingInt(B::getValue)));

【讨论】:

  • 为了简洁起见,我将答案更改为使用List#sort 而不是Collections.sort,但它会是一样的。
  • 这里不需要stream().forEach(…)。您可以在List 上致电forEach(…)
  • @Holger 谢谢,我知道这仍然有些奇怪
【解决方案2】:
 for(B b:listOfB) {
     System.out.print(" ; notes: "+b.getValue());
 }

可以改成

listOfB.stream().sorted(Comperator.comparing(B::getValue)).foreach(note -> System.out.print(" ; notes: " + note.getValue());

我认为这应该符合您的问题。

【讨论】:

  • 等等,我不明白。你想做什么?
【解决方案3】:

由于您只是想对 List&lt;B&gt; mBObjects 中的 B 对象进行排序,因此如果您将 B 设置为可比较的 并将它们添加到 TreeSet,那就太好了而不是ArrayList

mBObjects = new TreeSet<B>();

public class B implements Comparable<B>{
    private int mValue;

    //...
    public int compareTo(B b1){
       return this.mValue < b1.mValue? 1 : (this.mValue > b1.mValue? -1:0);
    }
}

【讨论】:

  • 您应该使用Integer.compare。此外,TreeSet 不允许重复,并且不会比排序列表更快。
猜你喜欢
  • 2018-09-10
  • 2013-02-13
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多