最近几天看了几篇有关于Java Map的外国博文,写得很是不错,因此整理了Java map 应该掌握的8个问题,都是平常开发司空见惯的问题,但愿对你们有帮助;若是有不正确的地方,欢迎提出,万分感谢哈~java
平常开发中,咱们常常遇到这种场景,把一个Map转化为List。map转List有如下三种转化方式:github
伪代码以下:json
// key list
List keyList = new ArrayList(map.keySet());
// value list
List valueList = new ArrayList(map.values());
// key-value list
List entryList = new ArrayList(map.entrySet());
复制代码
示例代码:数组
public class Test {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(2, "jay");
map.put(1, "whx");
map.put(3, "huaxiao");
//把一个map的键转化为list
List<Integer> keyList = new ArrayList<>(map.keySet());
System.out.println(keyList);
//把map的值转化为list
List<String> valueList = new ArrayList<>(map.values());
System.out.println(valueList);
把map的键值转化为list
List entryList = new ArrayList(map.entrySet());
System.out.println(entryList);
}
}
复制代码
运行结果:安全
[1, 2, 3]
[whx, jay, huaxiao]
[1=whx, 2=jay, 3=huaxiao]
复制代码
咱们常常须要遍历一个map,能够有如下两种方式实现:bash
for(Entry entry: map.entrySet()) {
// get key
K key = entry.getKey();
// get value
V value = entry.getValue();
}
复制代码
实例代码:ide
public class EntryMapTest {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(2, "jay");
map.put(1, "whx");
map.put(3, "huaxiao");
for(Map.Entry entry: map.entrySet()) {
// get key
Integer key = (Integer) entry.getKey();
// get value
String value = (String) entry.getValue();
System.out.println("key:"+key+",value:"+value);
}
}
}
复制代码
Iterator itr = map.entrySet().iterator();
while(itr.hasNext()) {
Entry entry = itr.next();
// get key
K key = entry.getKey();
// get value
V value = entry.getValue();
}
复制代码
实例代码:学习
public class IteratorMapTest {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(2, "jay");
map.put(1, "whx");
map.put(3, "huaxiao");
Iterator itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
// get key
Integer key = (Integer) entry.getKey();
// get value
String value = (String) entry.getValue();
System.out.println("key:"+key+",value:"+value);
}
}
}
复制代码
运行结果:ui
key:1,value:whx
key:2,value:jay
key:3,value:huaxiao
复制代码
对Map的keys进行排序,在平常开发很常见,主要有如下两种方式实现。
List list = new ArrayList(map.entrySet());
Collections.sort(list, (Entry e1, Entry e2)-> {
return e1.getKey().compareTo(e2.getKey());
});
复制代码
实例代码:
public class SortKeysMapTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("2010", "jay");
map.put("1999", "whx");
map.put("3010", "huaxiao");
List<Map.Entry<String,String>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, (Map.Entry e1, Map.Entry e2)-> {
return e1.getKey().toString().compareTo(e2.getKey().toString());
});
for (Map.Entry entry : list) {
System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue());
}
}
}
复制代码
SortedMap sortedMap = new TreeMap(new Comparator() {
@Override
public int compare(K k1, K k2) {
return k1.compareTo(k2);
}
});
sortedMap.putAll(map);
复制代码
实例代码:
public class SortKeys2MapTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("2010", "jay");
map.put("1999", "whx");
map.put("3010", "huaxiao");
SortedMap sortedMap = new TreeMap(new Comparator<String>() {
@Override
public int compare(String k1, String k2) {
return k1.compareTo(k2);
}
});
sortedMap.putAll(map);
Iterator itr = sortedMap.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
// get key
String key = (String) entry.getKey();
// get value
String value = (String) entry.getValue();
System.out.println("key:"+key+",value:"+value);
}
}
}
复制代码
运行结果:
key:1999,value:whx
key:2010,value:jay
key:3010,value:huaxiao
复制代码
List list = new ArrayList(map.entrySet());
Collections.sort(list, (Entry e1, Entry e2) ->{
return e1.getValue().compareTo(e2.getValue());
});
复制代码
实例代码:
public class SortValuesMapTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("2010", "jay");
map.put("1999", "whx");
map.put("3010", "huaxiao");
List <Map.Entry<String,String>>list = new ArrayList<>(map.entrySet());
Collections.sort(list, (Map.Entry e1, Map.Entry e2)-> {
return e1.getValue().toString().compareTo(e2.getValue().toString());
}
);
for (Map.Entry entry : list) {
System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue());
}
}
}
复制代码
运行结果:
key:3010,value:huaxiao
key:2010,value:jay
key:1999,value:whx
复制代码
初始化一个静态不可变的map,单单static final+static代码仍是不行的,以下:
public class Test1 {
private static final Map <Integer,String>map;
static {
map = new HashMap<Integer, String>();
map.put(1, "one");
map.put(2, "two");
}
public static void main(String[] args) {
map.put(3, "three");
Iterator itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
// get key
Integer key = (Integer) entry.getKey();
// get value
String value = (String) entry.getValue();
System.out.println("key:"+key+",value:"+value);
}
}
}
复制代码
这里面,map继续添加元素(3,"three"),发现是OK的,运行结果以下:
key:1,value:one
key:2,value:two
key:3,value:three
复制代码
真正实现一个静态不可变的map,须要Collections.unmodifiableMap,代码以下:
public class Test2 {
private static final Map<Integer, String> map;
static {
Map<Integer,String> aMap = new HashMap<>();
aMap.put(1, "one");
aMap.put(2, "two");
map = Collections.unmodifiableMap(aMap);
}
public static void main(String[] args) {
map.put(3, "3");
Iterator itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
// get key
Integer key = (Integer) entry.getKey();
// get value
String value = (String) entry.getValue();
System.out.println("key:"+key+",value:"+value);
}
}
}
复制代码
运行结果以下:
能够发现,继续往map添加元素是会报错的,实现真正不可变的map。
HashMap | TreeMap | Hashtable | ConcurrentHashMap | |
---|---|---|---|---|
有序性 | 否 | 是 | 否 | 否 |
null k-v | 是-是 | 否-是 | 否-否 | 否-否 |
线性安全 | 否 | 否 | 是 | 是 |
时间复杂度 | O(1) | O(log n) | O(1) | O(log n) |
底层结构 | 数组+链表 | 红黑树 | 数组+链表 | 红黑树 |
若是map是不可变的,能够这样建立:
Map map=Collections.emptyMap();
or
Map<String,String> map=Collections.<String, String>emptyMap();
//map1.put("1", "1"); 运行出错
复制代码
若是你但愿你的空map能够添加元素的,能够这样建立
Map map = new HashMap();
复制代码
有关于hashmap的复制,在平常开发中,使用也比较多。主要有=,clone,putAll
,可是他们都是浅复制,使用的时候注意啦,能够看一下如下例子:
例子一,使用=复制一个map:
public class CopyMapAssignTest {
public static void main(String[] args) {
Map<Integer, User> userMap = new HashMap<>();
userMap.put(1, new User("jay", 26));
userMap.put(2, new User("fany", 25));
//Shallow clone
Map<Integer, User> clonedMap = userMap;
//Same as userMap
System.out.println(clonedMap);
System.out.println("\nChanges reflect in both maps \n");
//Change a value is clonedMap
clonedMap.get(1).setName("test");
//Verify content of both maps
System.out.println(userMap);
System.out.println(clonedMap);
}
}
复制代码
运行结果:
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
Changes reflect in both maps
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}
复制代码
从运行结果看出,对cloneMap修改,两个map都改变了,因此=是浅复制。
例子二,使用hashmap的clone复制:
public class CopyCloneMapTest {
public static void main(String[] args) {
HashMap<Integer, User> userMap = new HashMap<>();
userMap.put(1, new User("jay", 26));
userMap.put(2, new User("fany", 25));
//Shallow clone
HashMap<Integer, User> clonedMap = (HashMap<Integer, User>) userMap.clone();
//Same as userMap
System.out.println(clonedMap);
System.out.println("\nChanges reflect in both maps \n");
//Change a value is clonedMap
clonedMap.get(1).setName("test");
//Verify content of both maps
System.out.println(userMap);
System.out.println(clonedMap);
}
}
复制代码
运行结果:
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
Changes reflect in both maps
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}
复制代码
从运行结果看出,对cloneMap修改,两个map都改变了,因此hashmap的clone也是浅复制。
例子三,经过putAll操做
public class CopyPutAllMapTest {
public static void main(String[] args) {
HashMap<Integer, User> userMap = new HashMap<>();
userMap.put(1, new User("jay", 26));
userMap.put(2, new User("fany", 25));
//Shallow clone
HashMap<Integer, User> clonedMap = new HashMap<>();
clonedMap.putAll(userMap);
//Same as userMap
System.out.println(clonedMap);
System.out.println("\nChanges reflect in both maps \n");
//Change a value is clonedMap
clonedMap.get(1).setName("test");
//Verify content of both maps
System.out.println(userMap);
System.out.println(clonedMap);
}
}
复制代码
运行结果:
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
Changes reflect in both maps
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}
复制代码
从运行结果看出,对cloneMap修改,两个map都改变了,因此putAll仍是浅复制。
那么,如何实现深度复制呢?
可使用序列化实现,以下为谷歌Gson序列化HashMap,实现深度复制的例子:
public class CopyDeepMapTest {
public static void main(String[] args) {
HashMap<Integer, User> userMap = new HashMap<>();
userMap.put(1, new User("jay", 26));
userMap.put(2, new User("fany", 25));
//Shallow clone
Gson gson = new Gson();
String jsonString = gson.toJson(userMap);
Type type = new TypeToken<HashMap<Integer, User>>(){}.getType();
HashMap<Integer, User> clonedMap = gson.fromJson(jsonString, type);
//Same as userMap
System.out.println(clonedMap);
System.out.println("\nChanges DO NOT reflect in other map \n");
//Change a value is clonedMap
clonedMap.get(1).setName("test");
//Verify content of both maps
System.out.println(userMap);
System.out.println(clonedMap);
}
}
复制代码
运行结果:
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
Changes DO NOT reflect in other map
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}
{1=User{name='test', age=26}, 2=User{name='fany', age=25}}
复制代码
从运行结果看出,对cloneMap修改,userMap没有被改变,因此是深度复制。