Reputation: 417
I have the following case:
SortedSet<MyClass> sortedSet = ...;
SortedSet<HeavyToCompare> newSet = ...;
for (MyClass m: sortedSet ){
newSet.add(m.getHeavyToCompare())
}
I want to avoid reordering of the newSet because HeavyToCompare it's very expensive to compare. Rather i want to keep the insertion order (that is the same of the original set). I understand that I can create a simple comparator that always return -1, but this breaks the contract of compareTo. What's the best practice here? I would need something like
SortedSet<K> result = Sets.transformAndKeepOrder(SortedSet<T> from, Function<T, K> function)
UPDATE: I cannot change the SortedSet, it is a requirement
Upvotes: 0
Views: 593
Reputation: 4002
You can hardcode a comparison order with Guava's Ordering.explicit
. However, this produces a limited SortedSet
. Specifically, its comparison methods (headSet
, etc.) will work only when their arguments are members of the set. After all, Ordering.explicit
only knows how to compare the values that you provide it. More concretely:
// In the real code, this values list will be computed in your loop:
List<Integer> values = Arrays.asList(2, 4, 6, 8);
Comparator<Integer> comparator = Ordering.explicit(values);
SortedSet<Integer> set = Sets.newTreeSet(comparator);
set.addAll(values);
set.headSet(4); // OK: [2]
set.headSet(5); // exception: "Cannot compare value: 5"
Upvotes: 0
Reputation: 425428
You could use a LinkedHashSet
, which is a Set
that iterates in insertion order:
Set<HeavyToCompare> newSet = new LinkedHashSet<HeavyToCompare>();
However, it is not a SortedSet
, but hopefully that is not a requirement.
Upvotes: 1
Reputation: 65889
I would attempt to record the position in the sortedSet
the object appears in. You could then compare the positions before calling the heavy compare.
How you achieve that will depend on a lot more of your code.
Upvotes: 0