(三十九)HashMap、HashTable、TreeMap、WeakHashMap有什么区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jiangshangchunjiezi/article/details/88029721

java.util.Map接口三个实现类:

—Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的JDK1.0
—-HashMap:底层是哈希表数据结构,允许使用null键null值,该集合不同步JDK1.2
—–TreeMap:底层是二叉树数据结构,线程不同步。可以用于给map集合中的键进行排序。
与Set很像。Set底层就是使用了Map集合

遍历的两种方法:https://blog.csdn.net/jiangshangchunjiezi/article/details/75268866

一、HashMap、HashTable、TreeMap

HashMap是最常用的Map,根据键的HashCode值存储数据,根据键可以直接获取它的值【V get(Object key)】,它具有很快的访问速度

相同点:都采用了hash法进行索引

不同点:

①HashMap是HashTable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),而HashTable不允许

import java.util.HashMap;//继承了java.util.AbstractMap
import java.util.Hashtable; //继承了java.util.Hashtable
public class HelloWorld {
    public static void main(String []args) {
      HashMap<Integer,String> hm=new HashMap<Integer,String>();
	  hm.put(1,"001");
	  System.out.println(hm.containsKey(1));
	  System.out.println(hm.containsValue("001"));
	
       Hashtable<Integer,String> ht=new Hashtable<Integer,String>();
       ht.put(null,"001");//会报空指针异常
	  }
}

②HashMap废弃了HashTable的contains方法去掉了,改成containsvalue和containsKey

两者中都有containsValue和containsKey

③HashMap里面存入的键值对在取出时,没有固定的顺序,是随机的。

扫描二维码关注公众号,回复: 5421364 查看本文章

④一般而言,在Map中插入、删除和定位元素,HashMap是最好的选择。由于TreeMap实现了SortMap接口,能够把它保存的记录根据键排序,因此,取出来的是排序后的键值对,如果需要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。

解释:在使用自然排序时候,分为两种情况:一种是JDK定义的对象;一种是我们自己定义的对象

自然排序要求被比较的元素实现Comparable接口(实现int compareTo(T o)),否则会报异常。

①jdk定义的对象:

public final class Integer extends Numberimplements Comparable<Integer>

public int compareTo(Integer anotherInteger)//数字,从小到大

②自己定义的对象

参考TreeSet练习:https://blog.csdn.net/jiangshangchunjiezi/article/details/75212387

public class SortedTest implements Comparable<SortedTest> {
    private int age;
    public SortedTest(int age){
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    //自定义对象,实现compareTo(T o)方法:
    public int compareTo(SortedTest sortedTest) {
        int num = this.age - sortedTest.getAge();
        //为0时候,两者相同:
        if(num==0){
            return 0;
        //大于0时,传入的参数小:
        }else if(num>0){
            return 1;
        //小于0时,传入的参数大:
        }else{
            return -1;
        }
    }
}

public class TreeMapTest {
    public static void main(String[] agrs){
        //自然顺序比较
        naturalSort();
    }
     //自然排序顺序:
    public static void naturalSort(){
        //第一种情况:Integer对象
        TreeMap<Integer,String> treeMapFirst = new TreeMap<Integer, String>();
        treeMapFirst.put(1,"jiaboyan");
        treeMapFirst.put(6,"jiaboyan");
        treeMapFirst.put(3,"jiaboyan");
        treeMapFirst.put(10,"jiaboyan");
        treeMapFirst.put(7,"jiaboyan");
        treeMapFirst.put(13,"jiaboyan");
        System.out.println(treeMapFirst.toString());

        //第二种情况:SortedTest对象
        TreeMap<SortedTest,String> treeMapSecond = new TreeMap<SortedTest, String>();
        treeMapSecond.put(new SortedTest(10),"jiaboyan");
        treeMapSecond.put(new SortedTest(1),"jiaboyan");
        treeMapSecond.put(new SortedTest(13),"jiaboyan");
        treeMapSecond.put(new SortedTest(4),"jiaboyan");
        treeMapSecond.put(new SortedTest(0),"jiaboyan");
        treeMapSecond.put(new SortedTest(9),"jiaboyan");
        System.out.println(treeMapSecond.toString());
    }
}

V put(K,V)

⑤HashTable的方法是线程安全的,而HashMap不支持线程的同步,所以它不是线程安全的。在多线程访问HashTable时,不需要开发人员对它进行同步,而对于HashMap,开发人员必须提供额外的同步机制。所以,就效率而言,HashMap可能高于HashTable

Q1:在HashTable上下文中,同步指什么

A:同步意味这在同一个时间点只能有一个线程可以修改hash表,任何线程在执行HashTable的更新操作前都需要获取对象锁,其他线程则等待锁的释放

Q2:如何实现HashMap的同步?

A:HashMap可以通过Map m=Collections.synchronizedMap(new HashMap())达到同步的效果。具体而言,该方法返回一个同步的Map,该Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是多线程下,也是安全的。

// 返回由指定映射支持的同步(线程安全的)映射。

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)

⑥HashTable使用Enumeration,HashMap使用Iterator

HashTable和HashMap均有keySet()和entrySet()方法。

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;
public class Woman {
	
	
	public static void main(String []args) {
	      HashMap<Integer,String> hm=new HashMap<Integer,String>();
		  hm.put(1,"001");
		  hm.put(2,null);
		  hm.put(null,"003");
		  //第一种遍历方式
		  Set<Integer> s=hm.keySet();
		  Iterator<Integer> it=s.iterator();
		  while(it.hasNext()){
			  System.out.println(hm.get(it.next()));
		  }
		 //第二种遍历
		  Set<Entry<Integer,String>> me=hm.entrySet();
		  Iterator<Entry<Integer,String>> its=me.iterator();
		  while(its.hasNext())
		  {
			  Entry<Integer, String> kv=its.next();
			  System.out.println(kv.getKey()+"----"+kv.getValue());
		  }
			
   }
}
import java.util.Enumeration;
import java.util.Hashtable;
public class HelloWorld {
    public static void main(String []args) {
       Hashtable<Integer,String> ht=new Hashtable<Integer,String>();
       ht.put(1,"001");
	   ht.put(2,"002");
	   ht.put(3,"003");
//elements():取出所有的值
	   Enumeration<String> enu=ht.elements(); //enum在java中是个关键字
	   
		while(enu.hasMoreElements())
		{
			System.out.println(enu.nextElement());
		}
    }
}

⑦LinkedHashMap是hashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按照读取顺序来排序

二、WeakHashMap、HashMap

WeakHashMap中的key采用的是“弱引用”的方式,只要WeakHashMap中的key不再被外部引用,它就可以被垃圾回收器回收。而HashMap中的key采用的是“强引用的方式”,当HashMap中的key没有被外部引用时,只有在这个key从HashMap中删除后,才可以被垃圾回收器回收。

猜你喜欢

转载自blog.csdn.net/jiangshangchunjiezi/article/details/88029721