按属性排序列表,但保持相同属性的顺序

时间:2016-01-27 08:45:40

标签: java algorithm sorting

我的列表可能如下所示:

{A[1], A[2], B[1], A[3], B[2], B[3], A[4]}

A,B是列表中对象的属性 数字表示具有相同属性的彼此相关的对象的顺序

现在,我想对列表进行排序,以便得到以下结果:

{A[1],A[2],A[3],A[4],B[1],B[2],B[3]}

具体来说,这意味着与具有相同属性的每个其他对象相关的对象的顺序应该保持不变,但是一般顺序应该是属性。问题是彼此相关的顺序不能通过附加属性来确定,它只是由根列表中的顺序指定。

我怎么能这样做?

4 个答案:

答案 0 :(得分:1)

只需定义一个新的比较器,在其中指定您的要求:检查对象是否具有相同的属性,并在这种情况下指定根列表中位置的优先级;否则,按属性本身排序。

Collections.sort(rootlist, new YourComparator());

class YourComparator implements Comparator<YourClass> {
    @Override
    public int compare(YourClass a, YourClass b) {
        if(a.attribute == b.attribute){
            return rootlist.indexOf(a) < rootlist.indexOf(b) ? -1 : rootlist.indexOf(a) == rootlist.indexOf(b) ? 0 : 1;
        }
        else 
            return a.attribute < b.attribute ? -1 : 1;

    }
}

答案 1 :(得分:1)

只需使用List.sort方法根据属性值对所有元素进行排序。

具有相同属性值的元素将保持与插入顺序相同的顺序。

例如:

@Test
public void testSortList() {

    List<Element> list = new ArrayList<>();
    list.add(new Element("A", 1));
    list.add(new Element("A", 2));
    list.add(new Element("B", 1));
    list.add(new Element("A", 3));
    list.add(new Element("B", 2));

    list.sort((element1, element2) -> element1.getValue().compareTo(element2.getValue()));

    assertThat(list.get(0).getValue()).isEqualTo("A");
    assertThat(list.get(0).getPosition()).isEqualTo(1);
    assertThat(list.get(1).getValue()).isEqualTo("A");
    assertThat(list.get(1).getPosition()).isEqualTo(2);
    assertThat(list.get(2).getValue()).isEqualTo("A");
    assertThat(list.get(2).getPosition()).isEqualTo(3);
    assertThat(list.get(3).getValue()).isEqualTo("B");
    assertThat(list.get(3).getPosition()).isEqualTo(1);
    assertThat(list.get(4).getValue()).isEqualTo("B");
    assertThat(list.get(4).getPosition()).isEqualTo(2);
}

Element类看起来如下:

class Element {

  /** Attribute used to sort the elements */
  private String value;

  /** Attribute used to remember the original position of this element in the list */
  private int position;

  public Element(String value, int position) {
    this.value = value;
    this.position = position;
  }

  public String getValue() {
    return value;
  }

  public int getPosition() {
    return position;
  }

  /** Insert equals and hashCode! */
}

答案 2 :(得分:0)

我不确定,如果已经实现的方法list.sort()维持你的条件,那么我建议你用O(n²)计算进行简单排序,假设你的compare - 方法返回0,如果属性是相同的:

List<T> sortList(List<T> list){
    for(int ind=1; ind<list.size(); ind++){
        for(int indBack=ind; indBack>0; indBack--){
            if(compare(list.get(indBack), list.get(indBack-1))==1){
                T tempSave = list.get(indBack-1);
                list.set(indBack-1, list.get(indBack));
                list.set(indBack, tempSave);
            }
        }
    }
    return list;
}

答案 3 :(得分:0)

您可以使用stable sort algorithm

不知道Java内置方法是否使用了一些稳定的排序(如TimSort)。如果没有,您可以轻松找到插入排序或合并排序实现。