Which interface represents a LinkedHashSet with iteration of insertion order

Sonar picks me up because of the following line of code:

public void setFileNames(LinkedHashSet<String> fileNames) { 

With the error message:

Avoid using implementation types like LinkedHashSet; use the interface instead

How does this happen when I want to present an unsorted Set that preserves its insertion order? Am I just using Set and making it clear that the iteration order will be preserved?

The stored data will be serialized using JaxB, and the iteration order is necessary after deserialization.

(I know and fully understand this )

+5
source share
4 answers

There is no such interface , since it makes no sense to require such behavior for input. The code that creates the Set may be intent on ordering and choose the appropriate implementation when creating the Set .

But how can the question arise whether a Set an insertion order, alphabetical order or arbitrary, for example. hash, order matters for a method like setFileNames(Set<String> fileNames) ?

Declaring a parameter type as Set gives you a guarantee that there will be no duplicates that affect behavior, but the insertion order is meaningless information (if the caller does not make it meaningful) about the history of Set .

If you insist on having the signature of the setFileNames(LinkedHashSet<String> fileNames) method setFileNames(LinkedHashSet<String> fileNames) , I can still pass Set with a meaningless order, for example. call
setFileNames(new LinkedHashSet<String>(hashSet)) or a set with lexicographic order, for example. setFileNames(new LinkedHashSet<String>(treeSet)) . Your signature makes it even more complex.

+3
source

I appreciate the other answers, and I also appreciate the sonar warning. However, sometimes (for example, perhaps in your case) everything is in order to ignore the warning. It seems to me that you are using LinkedHashSet to pinpoint the responsibilities of the caller. The set does not meet your requirements (the order is not saved). Also there is no list (individual items are not guaranteed). Therefore, it may be normal to ignore this warning.

The alternative is that you allow the list, and then you need to double check (inside your method) that the list has no duplicates and throws an exception if there is one. It seems funny to me.

Like others, you just need to figure out how to suppress a warning in Sonar. I hope this mechanism allows you to include the reason why you suppressed it. Then you can explain your decision to future attendants.

+1
source

Just accept Set , let the caller decide which implementation should go through.

which retains its insertion order?

This is up to the caller. LinkedHashSet maintains the order base upon insertion; TreeSet maintains order based on natural ordering. Why should your method care about how order is achieved?

+1
source

If you need the items you receive for the order, then your method should get a list, not a set. But to get rid of the warning, you will have to use Set, not LinkedHashSet. It is good practice to use interfaces rather than actual classes in your methods. You should not disclose actual implementations of the interface.

Also, if you only need to iterate over the elements of the set, you can get an Iterator and just iterate over it.

EDIT: if you really want you to get only a LinkedHashSet, you can do something like this:

 public void setFileNames(Set<String> fileNames) { if (!(fileNames instanceof LinkedHashSet)) { throw new IllegalArgumentException("I need a LinkedHashSet!"); } } 

EDIT 2: I don't think there is a perfect answer here, but if you really need everything to get a LinkedHashSet, I would declare it in the interface and find a way to force Sonar to ignore this particular instance of this warning.

-1
source

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


All Articles