您好,登錄后才能下訂單哦!
這篇文章主要介紹了java集合的實(shí)現(xiàn)代碼怎么寫(xiě)的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇java集合的實(shí)現(xiàn)代碼怎么寫(xiě)文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。
public class HashMapDemo { private Map map = null; public void init() { map = new HashMap(); map.put("a", "aaa"); map.put("b", "bbb"); map.put("c", "ccc"); System.out.println(map); } // 添加元素 public void testPut() { // V put(K key, V value) :把指定的key和value添加到集合中 map.put("a1", "aaa"); map.put("b1", "bbb"); map.put("c1", "ccc"); System.out.println(map); // void putAll(Map<? extends K,? extends V>m) :把指定集合添加集合中 Map map1 = new HashMap(); map1.put("e", "eee"); map1.put("f", "fff"); map.putAll(map1); System.out.println(map); // default V putIfAbsent(K key, V value) :如果key不存在就添加 map.putIfAbsent("a", "hello"); System.out.println(map); map.putIfAbsent("g", "ggg"); System.out.println(map); } // 修改元素 public void testModify() { // V put(K key, V value) :把集合中指定key的值修改為指定的值 map.put("a", "hello"); map.put("a", "world"); System.out.println(map); // 說(shuō)明,當(dāng)key相同時(shí),后面的值會(huì)覆蓋前面的值。 // default V replace(K key, V value) :根據(jù)key來(lái)替換值,而不做增加操作 Object replace = map.replace("b1", "java"); System.out.println(replace); System.out.println(map); //default boolean replace(K key, V oldValue,V newValue) } // 刪除元素 public void testRemove() { // V remove(Object key) :根據(jù)指定key刪除集合中對(duì)應(yīng)的值 Object c = map.remove("c"); System.out.println(c); System.out.println(map); // default boolean remove(Object key, Objectvalue) :根據(jù)key和value進(jìn)行刪除 map.remove("b", "bbb1"); System.out.println(map); // void clear() :清空集合中所有元素 map.clear(); System.out.println(map); } // 判斷元素 public void testJudge() { // boolean isEmpty() :判斷集合是否為空,如果是返回true,否則返回false System.out.println(map.isEmpty()); // boolean containsKey(Object key) :判斷集合中是否包含指定的key,包含返回true,否則返回false boolean flag = map.containsKey("a"); System.out.println(flag); // true flag = map.containsKey("a1"); System.out.println(flag); // false // boolean containsValue(Object value) :判斷集合中是否包含指定的value,包含返回true,否則返回false flag = map.containsValue("aaa"); System.out.println(flag); // true flag = map.containsValue("aaa1"); System.out.println(flag); // false } // 獲取元素 public void testGet() { // int size() :返回集合的元素個(gè)數(shù) int size = map.size(); System.out.println(size); // V get(Object key) :根據(jù)Key獲取值,如果找到就返回對(duì)應(yīng)的值,否則返回null Object val = map.get("a"); System.out.println(val); val = map.get("a1"); System.out.println(val); // null // default V getOrDefault(Object key, VdefaultValue) :根據(jù)Key獲取值,如果key不存在,則返回默認(rèn)值 val = map.getOrDefault("a1", "hello"); System.out.println(val); // Collection<V> values() :返回集合中所有的Value Collection values = map.values(); for (Object value : values) { System.out.println(value); } // Set<K> keySet() :返回集合中所有的Key Set set = map.keySet(); for (Object o : set) { System.out.println(o); } } // 迭代元素 public void testIterator() { // 第一種:通過(guò)key獲取值的方式 Set keySet = map.keySet(); Iterator it = keySet.iterator(); while (it.hasNext()) { Object key = it.next(); Object val = map.get(key); System.out.println(key + "=" + val); } System.out.println("------------------------ "); // 第二種:使用for循環(huán) for (Object key : map.keySet()) { System.out.println(key + "=" + map.get(key)); } System.out.println("------------------------ "); // 第三種:使用Map接口中的內(nèi)部類來(lái)完成,在框架中大量使用 Set entrySet = map.entrySet(); for (Object obj : entrySet) { Map.Entry entry = (Map.Entry) obj; System.out.println(entry.getKey() + "=" + entry.getValue()); } } }
說(shuō)明:在HashMap中鍵-值允許為空,但鍵唯一,值可重復(fù)。hashMap不是線程安全的。
是一個(gè)有序的集合,默認(rèn)使用的是自然排序方式。
public class Person implements Comparable { private String name; private int age; @Override public int compareTo(Object o) { if (o instanceof Person) { Person p = (Person) o; return this.age - p.age; } return 0; } public Person() {} public Person(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
測(cè)試
public class TeeMapDemo { @Test public void testInteger() { TreeMap tm = new TreeMap(); tm.put(3, 333); tm.put(2, 222); tm.put(11, 111); tm.put(2, 222); System.out.println(tm); } @Test public void testString() { TreeMap tm = new TreeMap(); tm.put("hello", "hello"); tm.put("world", "world"); tm.put("about", ""); tm.put("abstract", ""); System.out.println(tm); } @Test public void testPerson() { TreeMap tm = new TreeMap(new Comparator(){ @Override public int compare(Object o1, Object o2) { if (o1 instanceof Person && o2 instanceof Person) { Person p1 = (Person) o1; Person p2 = (Person) o2; return p1.getAge() - p2.getAge(); } return 0; } }); tm.put(new Person("張三",18), null); tm.put(new Person("李四",17), null); System.out.println(tm); } }
說(shuō)明:從上面的代碼可以發(fā)現(xiàn),TreeMap的使用和TreeSet的使用非常相似,觀察HashSet集合的源代碼可以看出,當(dāng)創(chuàng)建 HashSet集合時(shí),其實(shí)是底層使用的是HashMap。
public HashSet() { map = new HashMap<>(); }
HashSet實(shí)際上存的是HashMap的Key。
在Map集合中我們介紹了HashMap
,TreeMap
,在多線程的情況下這些集合都不是線程安全的,因此可能出現(xiàn)線程安全的問(wèn)題。
在Java中Hashtable是一種線程安全的HashMap
,Hashtable
在方法上與HashMap
并無(wú)區(qū)別,僅僅只是在方法使用了synchronized
以此來(lái)達(dá)到線程安全的目的,我們觀察Hashtable的源碼。
public synchronized V get(Object key) { Entry<?,?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { return (V)e.value; } } return null; }
以上是Hashtable的get源碼,可以看出它僅僅只是在方法上添加了鎖,這大大降低了線程的執(zhí)行效率,以犧牲效率的形式來(lái)達(dá)到目的,這顯然不是我們?cè)趯?shí)際中想要的,因此我們需要一種既能在線程安全方面有保障,在效率上還可以的方法。
ConcurrentHashMap采用的是分段鎖的原理,我們觀察源碼。
public V put(K key, V value) { return putVal(key, value, false); } final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException(); int hash = spread(key.hashCode()); int binCount = 0; for (Node<K,V>[] tab = table;;) { Node<K,V> f; int n, i, fh; if (tab == null || (n = tab.length) == 0) tab = initTable(); else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null))) break; // no lock when adding to empty bin } else if ((fh = f.hash) == MOVED) tab = helpTransfer(tab, f); else { V oldVal = null; synchronized (f) { if (tabAt(tab, i) == f) { if (fh >= 0) { binCount = 1; for (Node<K,V> e = f;; ++binCount) { K ek; if (e.hash == hash && ((ek = e.key) == key || (ek != null && key.equals(ek)))) { oldVal = e.val; if (!onlyIfAbsent) e.val = value; break; } Node<K,V> pred = e; if ((e = e.next) == null) { pred.next = new Node<K,V>(hash, key, value, null); break; } } } else if (f instanceof TreeBin) { Node<K,V> p; binCount = 2; if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, value)) != null) { oldVal = p.val; if (!onlyIfAbsent) p.val = value; } } } } if (binCount != 0) { if (binCount >= TREEIFY_THRESHOLD) treeifyBin(tab, i); if (oldVal != null) return oldVal; break; } } } addCount(1L, binCount); return null; }
從源碼中可以看出ConcurrentHashMap
僅僅是在當(dāng)有線程去操作當(dāng)前數(shù)據(jù)的時(shí)候添加了鎖,因此效率大大提高了。
在線程安全的情況下提高了效率。
關(guān)于“java集合的實(shí)現(xiàn)代碼怎么寫(xiě)”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“java集合的實(shí)現(xiàn)代碼怎么寫(xiě)”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。