"IndexedSet", "MapSet" or "SetMap" in Java

I am looking for a Java implementation of Set that provides a search on the properties of elements. Thinking in terms of Guava, it can be created using Function<Element, SearchKey> (it is expected to be unique to all elements of the set) and will provide a find(SearchKey key) method that returns an Element for which the function will return key .

Obvious assumptions that must be satisfied:

  • The result of the function(element) is constant for the entire lifetime of the Element in the set. Function
  • gives unique results for all elements of the set

Cause:
Sometimes there is a need for Set<Element> , and the type of the field cannot be changed to Map<SearchKey, Element> (for example, in the JPA entity or in the case of the 4th batch code). However, when building such an object, you can safely use your own implementation of Set with Map capabilities.

Alternatives:

There are several alternatives that I have already found, none of which seem perfect

  • does not have Map capabilities - using linear search to implement find(SearchKey) (works with each implementation of Set :)
  • using a TreeSet with Comparator comparing SearchKeys is a bit like a hack , especially since it no longer respects element equality
    the "find" method is called ceiling and requires you to build an artificial Element for search purposes (uogh ...)
  • "equivalence set" ( http://code.google.com/p/guava-libraries/issues/detail?id=576 ) - but this is not implemented and does not seem to be

( If you want to answer that you do not know more alternatives - save your time and do not do this. This is what I already know, I can not accept your answer.)

+4
source share
3 answers

I have to miss something, otherwise it's pretty easy using ForwardingSet to HashBiMap.keySet() . My trivial implementation only cares about add and addAll , all other things should work without any effort. There is no single test, I would recommend using a Guava test sheet for this.

+1
source

I am looking for a set implementation in Java that provides a search on the properties of elements.

This is what the map is intended for, and yes, you need to create a key object to represent what if you are looking.

This is the simplest and most effective solution in Java, so although it is a bit unpleasant, I would not worry about that.

BTW: Sets are usually implemented as a layer on top of the Map in the JRE, which is not ideal IMHO.

+2
source

If I understand your question correctly, 2 options come to my mind:

  • Your hack option: a TreeSet with a comparator that compares YourSearchKey with YourElement . You can either trick the type system or create a common interface, YourAbstractSearchKey . The only disadvantages are:
    • YourSearchKey objects can be inserted into Set . Collections.checkedSet() can help with this question.
    • The search result will most likely need to be attributed to YourElement . Workaround: Define all the properties in the common interface YourAbstractSearchKey and implement the implementation of YourSearchKey throw UnsupportedOperationException for additional ones.
  • Similarly, but with a map. You do not need to add additional properties to YourAbstractSearchKey , because the Map will be Map<YourAbstractSearchKey,YourElement> . To add elements you need to write myMap.put(newElement,newElement) .
+1
source

Source: https://habr.com/ru/post/1498314/


All Articles