我有一个类
项目的数组列表Class foo {
String name;
String time;
}
我想获得一个具有唯一名称的foo对象列表。如果列表中的两个对象具有相同的名称,我想只保留一个时间最短的对象(lexicographic很好)。此列表由底层库返回,因此我无法在插入时执行任何操作。我知道在O(n)时间和空间(最坏的情况)中使用地图很容易。有更有效的解决方案吗?
答案 0 :(得分:2)
有什么问题:
// myList is the List returned by the library
List<foo> new List = new ArrayList<foo>(new LinkedHashSet<foo>(myList));
覆盖equals()
中的hashCode()
和foo
。
此列表由底层库返回,因此我无法在插入时执行任何操作。我知道在O(n)时间和空间(最坏的情况)中使用地图很容易。有更有效的解决方案吗?
我相信不,这是最优化的解决方案。看看这个SO answer。
答案 1 :(得分:1)
为什么您不是简单地使用java.util.Set
,也不要忘记覆盖equals
类的hashCode
和foo
方法。
答案 2 :(得分:0)
即使有办法修改类以获得正确的哈希码,问题仍然是,应该是哪个哈希码。通常,哈希码和相等性使用对象的所有属性,因此这样的标准实现在这里没有帮助,因为您希望拥有关于实例的单个属性的唯一对象。
没有标准的哈希映射允许您提供自定义哈希和相等功能,但您可以为已排序的映射执行此操作。这不会给你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;
}