Kysil Ivan
Kysil Ivan

Reputation: 1037

Java sorted Collection impl that allows many equal values

I tried to use TreeSet:

Comparator<Product> pc = (p1, p2) -> ((Double) p1.getPrice()).compareTo(p2.getPrice());
Set<Product> products = new TreeSet<>(pc);
products.add(new Product(10));
products.add(new Product(10));

but problem is that it can not contain more than one equal values in terms of Comparator, and so only one of the product will be in products set.

I need some Collection implementation, that will order newly inserted value, allow many equal(in terms of Comparator) values, and have insert complexity log(n) (possibly tree based impl)

Upvotes: 0

Views: 91

Answers (3)

Kysil Ivan
Kysil Ivan

Reputation: 1037

So,
PriorityQueue worked for me.

TreeMultiset did not. When I add two different objects:
products.add(new Product(10)); products.add(new Product(10));
it contains two links for first instance, and none for second()

Upvotes: 0

Ren&#233; Scheibe
Ren&#233; Scheibe

Reputation: 2080

In case you really need to order the elements at insert time you can use Guava's TreeMultiset.

Upvotes: 2

Boris the Spider
Boris the Spider

Reputation: 61148

A class in the JDK that matches your exact requirements is PriorityQueue. From the documentation:

An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.

And

Implementation note: this implementation provides O(log(n)) time for the enqueuing and dequeuing methods (offer, poll, remove() and add); linear time for the remove(Object) and contains(Object) methods; and constant time for the retrieval methods (peek, element, and size).


You can also carry on using TreeSet but provide a Comparator that gives a unique answer. For example, if your Product has a unique name:

Comparator<Product> pc = Comparator.comparing(Product::getPrice)
                         .thenComparing(Comparator.comparing(Product::getName));

Note the use of Comparator.comparing rather than your lambda - it's neater and more robust.

Upvotes: 4

Related Questions