假设我有一个包含两个属性的客户列表(GS Collections):id和age,我想对属性id应用不同的过滤器
FastList<Customer> customers ...
customers.distinct( ) //Hey here there's no overload to provide a custom comparator!
答案 0 :(得分:3)
distinct()
和toSet()
之间的区别在于distinct()
将保留顺序
从原始列表中,但都依赖于使用equals()
和hashCode()
的默认对象相等。
方法toSortedSet()
需要Comparator
,toSortedSetBy()
允许您传入Function
。两者都适合你。以下是toSortedSetBy()
使用Java 8的方式。
FastList<Customer> customers = ...;
MutableSortedSet<Customer> sortedSet = customers.toSortedSetBy(Customer::getId);
使用SortedSetIterable
有两个缺点。第一个是算法是O(n log n)而不是O(n)。第二个是SortedSetIterable
如果它的equals方法与比较器不一致会表现得很奇怪(即使它们具有相同的id,Customer.equals()也不会认为两个Customers等于。)
第二种方法是使用UnifiedSetWithHashingStrategy
。
FastList<Customer> customers = FastList.newListWith(c1, c2, c3);
UnifiedSetWithHashingStrategy<Customer> set =
new UnifiedSetWithHashingStrategy<>(HashingStrategies.fromIntFunction(Customer::getId));
set.addAll(customers);
这在O(n)时间内运行,但是你失去了订购。 GS Collections的distinct()
形式不需要HashingStrategy
,但您可以自己编写。
public static <T> FastList<T> distinct(
FastList<T> fastList,
HashingStrategy<T> hashingStrategy)
{
MutableSet<T> seenSoFar =
UnifiedSetWithHashingStrategy.newSet(hashingStrategy);
FastList<T> targetCollection = FastList.newList();
for (int i = 0; i < fastList.size(); i++)
{
if (seenSoFar.add(fastList.get(i)))
{
targetCollection.add(fastList.get(i));
}
}
return targetCollection;
}
你就这样使用它。
distinct(customers, HashingStrategies.fromIntFunction(Customer::getId));