public class Person {
private String name;
private long id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Person(String name, long id) {
super();
this.name = name;
this.id = id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Person [name=" + name + ", id=" + id + "]";
}
}
public class HashMapTest {
public void Test() {
Map hMap= new HashMap();
hMap.put("1", new Person("一", 11));
hMap.put("2", new Person("二", 22));
hMap.put("3", new Person("三", 33));
hMap.put("4", new Person("四", 44));
Iterator iterator = hMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry =(Map.Entry) iterator.next();
String keyString =(String) entry.getKey();
String value=String.valueOf(entry.getValue()) ;
System.out.println("key:"+keyString);
System.out.println("value:"+value);
}
//Hashtable
Hashtable<String, Person> hashtable=new Hashtable<String, Person>();
hashtable.put("1", new Person("一", 11));
hashtable.put("3", new Person("二", 22));
hashtable.put("2", new Person("三", 33));
hashtable.put("4", new Person("四", 44));
//Hashtable两种遍历方式Iterator与Enumeration
Iterator iterator2 = hashtable.entrySet().iterator();
while (iterator2.hasNext()) {
Entry object = (Entry) iterator2.next();
System.out.println(object);
}
Enumeration<Person> e = hashtable.elements();
while (e.hasMoreElements()) {
Person entry = e.nextElement();
System.out.println("Hashtable:"+entry);
}
//LinkedHashMap默认按插入顺序
Map lMap=new LinkedHashMap();
lMap.put("1", new Person("一", 11));
lMap.put("3", new Person("二", 22));
lMap.put("2", new Person("三", 33));
lMap.put("4", new Person("四", 44));
Iterator iterator3 = lMap.entrySet().iterator();
while (iterator3.hasNext()) {
Entry object = (Entry) iterator3.next();
System.out.println("LinkedHashMap插入顺序:"+object);
}
//LinkedHashMap如果指定按访问顺序排序,那么调用get方法访问后,会将这次访问的元素移至链表尾部,不断访问可以形成按访问顺序排序的链表。
Map lMap2=new LinkedHashMap(16,0.75f,true);
lMap2.put("1", new Person("一", 11));
lMap2.put("3", new Person("二", 22));
lMap2.put("2", new Person("三", 33));
lMap2.put("4", new Person("四", 44));
lMap2.get("2");//对key为2的访问
Iterator iterator4 = lMap2.entrySet().iterator();
while (iterator4.hasNext()) {
Entry object = (Entry) iterator4.next();
System.out.println("LinkedHashMap访问顺序:"+object);
}
//TreeMap默认是按键进行升序排序
Map tMap=new TreeMap();
tMap.put("3", new Person("三", 33));
tMap.put("1", new Person("一", 11));
tMap.put("2", new Person("二", 22));
tMap.put("4", new Person("四", 44));
Iterator iterator5 = tMap.entrySet().iterator();
while (iterator5.hasNext()) {
Entry object = (Entry) iterator5.next();
System.out.println("TreeMap默认排序:"+object);
}
//TreeMap自定义的排序方式
Map tMap2=new TreeMap(new Comparator<String>() {
//进行降序排序
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
return o2.compareTo(o1);
}
});
tMap2.put("3", new Person("三", 33));
tMap2.put("1", new Person("一", 11));
tMap2.put("2", new Person("二", 22));
tMap2.put("4", new Person("四", 44));
Iterator iterator6 = tMap2.entrySet().iterator();
while (iterator6.hasNext()) {
Entry object = (Entry) iterator6.next();
System.out.println("TreeMap自定义的排序:"+object);
}
}
public static void main(String[] args) {
HashMapTest test= new HashMapTest();
test.Test();
}
}
一、HashMap、Hashtable区别
1、继承不同
public class Hashtable extends Dictionary implements Map
public class HashMap extends AbstractMap implements Map
Dictionary它是任何可将键映射到相应值的类的抽象父类,而AbstractMap是基于Map接口的骨干实现,它以最大限度地减少实现此接口所需的工作。
2、HashMap存储的键值对,key可唯一有一个空值,value可以有多个空值。
Hashtable存储的键值对,key和value都不可有空值。
3、HashTable是线程安全的。
HashMap是非线程安全的。Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。
4、遍历方式上HashMap和Hashtable都可用Iterator,Hashtable还可用 Enumration 遍历
5、HashMap的默认数组大小为16,扩容增加的方式是2*old
Hashtable的默认数组大小为11,扩容增加的方式是 old*2+1。
6、哈希值的计算方法不同,Hashtable直接使用的是对象的hashCode,而HashMap则是在对象的hashCode的基础上还进行了一些变化
二、LinkedHashMap
public class LinkedHashMap<K, V> extends HashMap<K, V> implements Map<K, V>
LinkHashMap是HashMap的子类。它保存了记录的插入顺序。
LinkedHashMap定义了排序模式accessOrder,该属性为boolean型变量,对于访问顺序,为true;对于插入顺序,则为false。
默认情况下,在遍历的时候,会按插入顺序进行遍历。遍历的时候会比HashMap慢。
如果指定按访问顺序排序,那么调用get方法访问后,会将这次访问的元素移至链表尾部,不断访问可以形成按访问顺序排序的链表。
三、TreeMap
public class TreeMap<K,V>extends AbstractMap<K,V>implements NavigableMap<K,V>, Cloneable, Serializable
TreeMap能够把它保存的记录根据键进行排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。
四、Properties
properties类实现了Map接口,它是用map来存储key-value数据,所以存入数据也是无序的。只能通过key的方式来get对应value。
针对key-value这种配置文件,是用load方法就能直接映射成map。这种配置文件也是我们最重要碰到的配置文件,利用properties读取这类文件到内存一行代码就可以,比自己解析强大多了。
test.txt
#test.txt
name=11
sex = 2
public class LoadSample {
public static void main(String args[]) throws Exception {
Properties prop = new Properties();
FileInputStream fil =
new FileInputStream("test.txt");
prop.load(fil); //直接生产一个内存map
System.out.println("test.txt: " + prop.getProperty("name")); // get到对应的value了
Properties p = new Properties();
p.setProperty("id","111");
p.setProperty("password","123456");
try{
FileOutputStream fW = new FileOutputStream(new File("e:\\test1.txt"));
p.list(fW );//list方法是一个输出方法
} catch (IOException e) {
e.printStackTrace();
}
}
}
五、HashMap、HashSet区别
HashMap :实现map接口;使用hash算法,里面的数据是无序的;并且存储的是键值对;非线程安全;
HashSet :实现了Set接口;底层采用的是HashMap进行实现的,但是没有key-value,存储的是key不容许重复,value都为PRESENT;非线程安全;
六、关于同步 --引用
同步的集合类Hashtable
和 Vector
,以及同步的包装器类 Collections.synchronizedMap
和Collections.synchronizedList
,为Map
和 List
提供了基本的有条件的线程安全的实现。然而,某些因素使得它们并不适用于具有高度并发性的应用程序中——它们的 集合范围的单锁特性对于可伸缩性来说是一个障碍,而且,很多时候还必须在一段较长的时间内锁定一个集合,以防止出现ConcurrentModificationException
s异常。ConcurrentHashMap
和 CopyOnWriteArrayList
实现提供了更高的并发性,同时还保住了线程安全性,只不过在对其调用者的承诺上打了点折扣。ConcurrentHashMap
和 CopyOnWriteArrayList
并不是在您使用HashMap
或 ArrayList
的任何地方都一定有用,但是它们是设计用来优化某些特定的公用解决方案的。许多并发应用程序将从对它们的使用中获得好处。