【问题标题】:Sort an arraylist by an object property using the order of another arraylist with same type property in Java使用Java中具有相同类型属性的另一个数组列表的顺序按对象属性对数组列表进行排序
【发布时间】:2012-06-06 16:44:40
【问题描述】:

我有 2 个数组列表包含这样的对象:

第一个数组列表包含字符串和双精度:[a 1.1, b 1.2, d 0.4, g 1.9, f 0.5 等等...]

第二个数组列表包含字符串、双精度和整数:[b 0.1 2, f 1.1 5, g 2.3 1, a 1.1 2 等等...]

第二个数组列表可能包含与第一个相同或更多或更少的项目,但其所有字符串属性值将是仅存在于第一个字符串属性中的任何值。

我只需要根据第一个数组列表字符串属性的顺序对第二个数组列表进行排序。第一个数组列表已经有序,如果我对第二个进行排序,那么预期的输出将是:

[a 1.1 2,b 0.1 2,g 2.3 1,f 1.1 5 .....]

我已经看到了一些关于比较器的问题和答案,但他们都在使用一种类型的数组列表进行排序。但是在这里我有两种类型的arraylist,我真的不知道该怎么做!

因此,如果您有任何想法,请与我分享,如果可能的话,分享一些示例代码。

我是 stackoverflow 的新手,在 Java 方面没有太多经验。我在这种情况下遇到了很大的麻烦。在谷歌搜索和搜索之后,特别是在 stackoverflow 中,但无法获得任何有用的想法。以上情况我已经解释过了,如有错误请见谅!

谢谢!

【问题讨论】:

  • 这是作业吗?奇怪的是,家庭作业听起来也太奇怪了。
  • 第一个数组中的字符串是唯一的集合,还是有 2 个或更多对象的字符串属性相等?
  • @user845279: 第一个数组中没有字符串属性是唯一的。
  • "1st arraylist contains string and double" -- 你的意思是ArrayList的每个元素都是一个包含Stringdouble元素的对象吗?
  • @JimGarrison:是的,正如你所说。

标签: java sorting collections arraylist


【解决方案1】:

这很简单。这是一些伪 Java,它假定 list1 中没有重复键,并且不需要任何外部库。

假设以下...

class List1Item {
    String stringValue;
    double doubleValue;
};
class List2Item {
    String stringValue;
    double doubleValue;
    int    intValue;
};

List<List1Item> list1 = new ArrayList<>();
List<List2Item> list2 = new ArrayList<>();

一般的方法是在每个键值与其在第一个列表中的位置之间建立一个映射。

// Map to hold list1 key-to-position association
Map<String,Integer> sortKeys = new HashMap<>();

// Populate the key-to-position map with keys from list1
int pos=0;
for (List1Item i : list1)
    sortKeys.put(i.stringValue,pos++);

然后使用映射将list2的项目按list1中key的位置排序:

// Define a comparator that will use the map to sort list2 keys
Comparator<List2Item> comp = new Comparator<List2Item>() 
{
    public int compare(List2Item v1, List2Item v2)
    {
        return sortKeys.get(v1.stringValue).compareTo(sortKeys.get(v2.stringValue));
    }
}
Collections.sort(list2,comp);

【讨论】:

  • 非常感谢您的回复!您的示例适用于我的问题! :)
【解决方案2】:

让我们假设 list1list2 中的对象是 Foo 和 Bar 类型,它们都实现了一个方法 getString() ,它返回字符串属性。正如你所说,列表 1 中的字符串值是唯一的。

ArrayList<Foo> list1 = new ArrayList<Foo>();
ArrayList<Bar> list2 = new ArrayList<Bar>();

final HashMap<String, Integer> positions = new HashMap<String, Integer>();
for(int i=0;i<list1.size();i++){
    positions.put(obj.getString(), i);
}

Collections.sort(list2, new Comparator<Bar>(){
    public int compare(Bar obj1, Bar obj2){
        return positions.get(obj2.getString()) - positions.get(obj1.getString());
    }
});

【讨论】:

  • 非常感谢您的回复!得到我的解决方案!这就像一个魅力! :)
【解决方案3】:

这是一个相当复杂的问题,不会有任何真正简单的解决方案。

我能想到的最简单的就是依赖第三方库Guava了。 (披露:我是贡献者。)

我们将第一个对象类型称为Foo 和第二个对象类型Bar,因为您还没有命名它们。我还假设Bars 的String 字段在第二个列表中是唯一的

List<String> stringOrder = new ArrayList<String>();
for (Bar bar : list2) {
  stringOrder.add(bar.getString());
}
Ordering<String> stringComparator = Ordering.explicit(stringOrder);
// construct a String comparator based on that ordering
Ordering<Foo> fooOrdering = stringComparator.onResultOf(
  new Function<Foo, String>() {
    public String apply(Foo foo) {
      return foo.getString();
    }
  });
Collections.sort(list1, fooOrdering);

【讨论】:

  • 非常感谢您的回复! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
  • 2020-05-20
  • 2019-02-11
相关资源
最近更新 更多