Iterate over each Entry in a Maphtml
Iterating over every pair of key-value is the most basic operation to traverse a map. In Java, such pair is stored in the map entry called Map.Entry. Map.entrySet() returns a key-value set, therefore the most efficient way of going through every entry of a map isjava
Entry entry map. K key entry. V value entry. |
Sort a Map on the valuesapache
Putting the map into a list and sorting it works on this case too, but we need to compare Entry.getValue() this time. The code below is almost same as before.api
list map..list, @Override compareEntry e1, Entry e2 e1..e2. |
We can still use a sorted map for this question, but only if the values are unique too. Under such condition, you can reverse the key=value pair to value=key. This solution has very strong limitation therefore is not really recommended by me.oracle
4. Initialize a static/immutable Mapapp
When you expect a map to remain constant, it’s a good practice to copy it into an immutable map. Such defensive programming techniques will help you create not only safe for use but also safe for thread maps.ide
To initialize a static/immutable map, we can use a static initializer (like below). The problem of this code is that, although map is declared as static final, we can still operate it after initialization, like Test.map.put(3,"three");
. Therefore it is not really immutable. To create an immutable map using a static initializer, we need an extra anonymous class and copy it into a unmodifiable map at the last step of initialization. Please see the second piece of code. Then, an UnsupportedOperationException will be thrown if you run Test.map.put(3,"three");
.svn
Test map map map., map., Test map aMap aMap., aMap., map .aMap |
Guava libraries also support different ways of intilizaing a static and immutable collection. To learn more about the benefits of Guava’s immutable collection utilities, see Immutable Collections Explained in Guava User Guide.ui
A Map with reverse view/lookupthis
Sometimes, we need a set of key-key pairs, which means the map’s values are unique as well as keys (one-to-one map). This constraint enables to create an 「inverse lookup/view」 of a map. So we can lookup a key by its value. Such data structure is called bidirectional map, which unfortunetely is not supported by JDK.
Both Apache Common Collections and Guava provide implementation of bidirectional map, called BidiMap and BiMap, respectively. Both enforce the restriction that there is a 1:1 relation between keys and values.
7. Shallow copy of a Map
Most implementation of a map in java, if not all, provides a constructor of copy of another map. But the copy procedure is not synchronized. That means when one thread copies a map, another one may modify it structurally. To [prevent accidental unsynchronized copy, one should use Collections.synchronizedMap() in advance.
copiedMap .map |
Another interesting way of shallow copy is by using clone() method. However it is NOT even recommended by the designer of Java collection framework, Josh Bloch. In a conversation about 「Copy constructor versus cloning「, he said
I often provide a public clone method on concrete classes because people expect it. … It’s a shame that Cloneable is broken, but it happens. … Cloneable is a weak spot, and I think people should be aware of its limitations.
For this reason, I will not even tell you how to use clone() method to copy a map.
8. Create an empty Map
If the map is immutable, use
map . |
Otherwise, use whichever implementation. For example
map |
Efficient equivalent for removing elements while iterating the Collection
The only correct way to modify a collection while iterating is using Iterator.remove(). For example,
IteratorInteger itr list.itr. itr. |
One most frequent incorrect code is
i list list.i |
You will get a ConcurrentModificationException by running the above code. This is because an iterator has been generated (in for statement) to traverse over the list, but at the same time the list is changed by Iterator.remove(). In Java, 「it is not generally permissible for one thread to modify a collection while another thread is iterating over it.」
What is the best way to filter a Collection?
Again, you can use third-party package, like Guava or Apache Commons Lang to fullfil this function. Both provide a filter() method (in Collections2 of Guava and in CollectionUtils of Apache). The filter() method will return elements that match a given Predicate.
In JDK, things become harder. A good news is that in Java 8, Predicate will be added. But for now you have to use Iterator to traverse the whole collection.
IteratorInteger itr list.itr. i itr. i itr. |
Of course you can mimic the way of what Guava and Apache did, by introducing a new interface Predicate. That might also be what most advanced developers will do.
PredicateT testT o T filterCollectionT collection, PredicateT predicate collection predicate IteratorT itr collection. itr. T obj itr. predicate.obj itr. |
Then we can use the following code to filter a collection:
filterlist, PredicateInteger test i i |
Why is char[] preferred over String for security sensitive information?
Strings are immutable, which means once they are created, they will stay unchanged until Garbage Collector kicks in. With an array, you can explicitly change its elements. In this way, security sensitive information(e.g. password) will not be present anywhere in the system.
Joins the elements of the provided array into a single String
j StringUtils. , , , ..j |