Long Luo's Life Notes

每一天都是奇迹

By Long Luo

饮湖上初晴后雨二首·其二

苏轼

水光潋滟晴方好,山色空蒙雨亦奇。 欲把西湖比西子,淡妆浓抹总相宜。

年前的雪后环游西湖,只是走马观花匆匆一瞥。西湖真正的美,在于环绕西湖的山,有很多各具特色的路,每一条沿途风景都美不胜收。

这个周末,趁着春光,来一次西湖慢游。

正所谓“三面云山一面城,半城秋色半城湖”,西湖的东南,西南,西北三面环山,东北开阔为杭州市区。

从地图上看,杭州山并不多,但西湖周边的山就是生的巧,恰恰环着西湖,湖映山,山绕湖,西湖及周边的美立刻就无法比拟了。

如果没有这些山的映衬,西湖绝不会美到如斯。

西湖周边到处都是人文景观,众多园林庭院、故宅旧居,每一个名字、每一处建筑都可能有悠久绵长的历史,自然和人文的完美融合。

Long Luo@2018.03.26于杭州

By Long Luo

烟雨江南,如诗如画。

从中学课文和数不胜数的古诗词里,我学到了江南这个词。

在无数雨濛濛的日子,我都会枕着一首江南古曲,在想象的烟波桨声中,醉倒在江南水乡的温柔梦里。

江南,一个令无数人怦然心动的字眼; 江南,一个令无数人梦寐以求的地方。

江南的青山远黛,章台朱户,水榭亭阁,长街曲巷,黛瓦白墙,飞檐镂窗,杨柳长堤……

把整个江南构筑成一幅写意的泼墨山水画,让人留恋,让人神往。

对于江南,哪怕你巧手挥毫泼墨,她的百媚你永远也写不完,她的千色你永远也画不尽。江南,宛若一位古典女子,盈盈碎步,姿态翩跹,烟雨是她的面纱,她灵动的眸子里满是柔情。

烟水亭边,江南用翠柳丝绦绾就了我的情结,令我一生为之神迷,为之痴恋。

江南的雨,透着一缕缥缈,缠绵而多情,那种烟雨迷离的意境纵然用万千词阙都无法写尽它的深意。

Long Luo@2018年03月18日于杭州

By Long Luo

西溪的景色特点以天然质朴为美,若是选用四个字来概括,有人将其提练为:“冷、野、淡、雅”。

冷,就是静、僻,是都市中的一帖宁静剂; 野,就是天然、野趣,是红尘中的净土; 淡,就是淡雅、平淡,使人领悟回归自然的哲理; 雅,就是词人雅集、渔翁垂钓、冷梅馨香。

西溪以其优美的山水景色和朴素的田园风光,成为历代文人墨客休闲、养生和隐居的理想佳境,因而留下了大量的诗词、字画、碑文等胜迹。

By Long Luo@2018.02.26 in Hangzhou

By Long Luo

春节前在杭州的最后一个夜晚来市中心看钱塘江夜景。

城市因为有了水,才有了生机,河流和湖泊,总是城市里最美的一道风景!

城在水中映,但要成为美不胜收的风景,却并不容易。首先江面不能太窄,要不就成了河景、溪景,也不能太宽,太宽就失之亲切。

看过了这么多城市的江景,唯有黄浦江夜景是不能不看的。

一面是外滩,见证了上海滩沧桑历史,一面是陆家嘴,未来宏图画卷等待书写;一面是古典,一面是现代,交相辉映,相得益彰,尽显江岸美景。

相比之下,钱塘江的夜景缺乏像小蛮腰一样独具特色的地标。不过,钱塘江还有很多没有开发,相信很快就能看到。

杭州,明年见!

By Long Luo at 2018.02.14 in Bingjiang, Hangzhou, China.

In general, Map is a data structure consisting of a set of key-value pairs, and each key can only appears once in the map. This post summarizes Top 9 FAQ of how to use Java Map and its implemented classes. For sake of simplicity, I will use generics in examples. Therefore, I will just write Map instead of specific Map. But you can always assume that both the K and V are comparable, which means K extends Comparable and V extends Comparable.

1. Convert a Map to List

In Java, Map interface provides three collection views: key set, value set, and keyvalue set. All of them can be converted to List by using a constructor or addAll() method. The following snippet of code shows how to construct an ArrayList from a map.

1
2
3
4
5
6
// key list
List keyList = new ArrayList(map.keySet());
// value list
List valueList = new ArrayList(map.valueSet());
// key value list
List entryList = new ArrayList(map.entrySet());

2. iterate over each entry in a map

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.

3. SORT A MAP ON THE KEYS

Map.entrySet() returns a key-value set, therefore the most efficient way of going through every entry of a map is

1
2
3
4
5
6
for (Entry entry:map.entrySet()) {
// get key
K key = entry.getKey();
// get value
V value = entry.getValue();
}

Iterator can also be used, especially before JDK 1.5

1
2
3
4
5
6
7
8
Iterator itr = map.entrySet().iterator();
while(itr.hasNext()){
Entry entry = itr.next();
// get key
K key = entry.getKey();
// getvalue
V value = entry.getValue();
}

60.3 sort a map on the keys

Sorting a map on the keys is another frequent operation. One way is to put Map.Entry into a list, and sort it using a comparator that sorts the value.

Li s t l i s t = new Ar rayLi s t (map. ent rySe t ( ) ) ; Co l l e c t i ons . s o r t ( l i s t , new Comparator ( ) { @Override public int compare ( Entry e1 , Entry e2 ) { return e1 . getKey ( ) . compareTo ( e2 . getKey ( ) ) ; } });

The other way is to use SortedMap, which further provides a total ordering on its keys. Therefore all keys must either implement Comparable or be accepted by the comparator.

4. SORT A MAP ON THE VALUES

One implementing class of SortedMap is TreeMap. Its constructor can accept a comparator. The following code shows how to transform a general map to a sorted map.

SortedMap sortedMap = new TreeMap (new Comparator ( ) { @Override public int compare (K k1 , K k2 ) { return k1 . compareTo ( k2 ) ; } } ) ; sortedMap . putAll (map) ;

60.4 sort a map on the values

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.

Li s t l i s t = new Ar rayLi s t (map. ent rySe t ( ) ) ; Co l l e c t i ons . s o r t ( l i s t , new Comparator ( ) { @Override public int compare ( Entry e1 , Entry e2 ) { return e1 . getValue ( ) . compareTo ( e2 . getValue ( ) ) ; } } ) ;

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.

60.5 initialize a static/immutable map

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.

60.6. DIFFERENCE BETWEEN HASHMAP, TREEMAP, AND HASHTABLE

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”);.

public c l a s s Tes t { pr ivate s t a t i c f ina l Map map; s t a t i c { map = new HashMap ( ) ; map. put ( 1 , ” one ” ) ; map. put ( 2 , ” two ” ) ; } } public c l a s s Tes t { pr ivate s t a t i c f ina l Map map; s t a t i c { Map aMap = new HashMap ( ) ; aMap. put ( 1 , ” one ” ) ; aMap. put ( 2 , ” two ” ) ; map = Co l l e c t i ons . unmodifiableMap (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.

60.6 difference between hashmap, treemap, and hashtable

There are three main implementations of Map interface in Java: HashMap, TreeMap, and Hashtable. The most important differences include: The order of iteration. HashMap and HashTable make no guarantees as to the order of the map; in particular, they do not guarantee that the order

60.7. A MAP WITH REVERSE VIEW/LOOKUP 218 will remain constant over time. But TreeMap will iterate the whole entries according the “natural ordering” of the keys or by a comparator. key-value permission. HashMap allows null key and null values. HashTable does not allow null key or null values. If TreeMap uses natural ordering or its comparator does not allow null keys, an exception will be thrown. Synchronized. Only HashTable is synchronized, others are not. Therefore, “if a thread-safe implementation is not needed, it is recommended to use HashMap in place of HashTable.” A more complete comparison is | HashMap | HashTable | TreeMap i t e r a t i o n order | no | no | yes null key value | yes yes | yes yes | no yes synchronized | no | yes | no time performance | O( 1 ) | O( 1 ) | O( log n) implementation | buckets | buckets | red black t r e e Read more about HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap. 60.7 a map with reverse view/lookup 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. 60.8 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 60.9. FOR THIS REASON, I WILL NOT EVEN TELL YOU HOW TO USE CLONE() METHOD TO COPY one thread copies a map, another one may modify it structurally. To prevent accidental unsynchronized copy, one should use Collections.synchronizedMap() in advance.

Map copiedMap = Co l l e c t i ons.synchronizedMap (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.

60.9 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 = Co l l e c t i ons . emptyMap ( ) ;

Otherwise, use whichever implementation. For example map = new HashMap ( ) ;

THE

参考资料

Top 15+ Tricky HashMap Interview Questions (With Smart Answers) https://neesri.medium.com/top-15-tricky-hashmap-interview-questions-with-smart-answers-813f2bdbc108

A Deep Dive into Java Maps: The Ultimate Guide for All Developers https://dev.to/wittedtech-by-harshit/a-deep-dive-into-java-maps-the-ultimate-guide-for-all-developers-oig

0%