我有一个类项目的数组列表
Class foo {
String name;
String time;
}
我想得到一个具有唯一名称的foo对象列表。如果列表中的两个对象具有相同的名称,我希望只保留时间最少的一个(词典编纂是可以的)。这个列表是由一个底层库返回的,所以我在插入时不能做任何事情。我知道这对于O(n)时间和空间中的映射来说很容易(最坏的情况)。有没有更有效的解决方案?
有什么问题
// myList is the List returned by the library
List<foo> new List = new ArrayList<foo>(new LinkedHashSet<foo>(myList));
覆盖foo
中的equals()
和hashCode()
。
这个列表是由一个底层库返回的,所以我在插入时不能做任何事情。我知道这对于O(n)时间和空间中的映射来说很容易(最坏的情况)。有没有更有效的解决方案?
我认为没有,这是最优化的解决方案。看看这个SO的答案。
为什么不简单地使用java.util.Set
,并且不要忘记为foo
类重写equals
和hashCode
方法。
即使有一种方法可以修改类以获得正确的哈希代码,问题也会是,它应该是哪种哈希代码。通常,哈希代码和等式使用对象的所有属性,因此这样的标准实现在这里没有帮助,因为您希望拥有与实例的单个属性相关的唯一对象。
没有标准的哈希映射允许您提供自定义的哈希和相等函数,但您可以为排序的映射执行此操作。这不会像哈希一样给你O(1),但它可以给你O的查找(log(n)),它仍然比O(n)好。
以下是它的工作方式:
List<foo> list = // however you get it
Set<foo> set=new TreeSet<>(FooComparator.INSTANCE);
// now the set has no duplicates regarding foo.name
…
final class FooComparator implements Comparator<foo>
{
static final FooComparator INSTANCE = new FooComparator();
public int compare(foo o1, foo o2)
{
return o1.name.compareTo(o2.name);
}
}
class foo {
String name;
String time;
}