溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java集合的實(shí)現(xiàn)代碼怎么寫(xiě)

發(fā)布時(shí)間:2022-05-19 11:49:51 來(lái)源:億速云 閱讀:109 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要介紹了java集合的實(shí)現(xiàn)代碼怎么寫(xiě)的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇java集合的實(shí)現(xiàn)代碼怎么寫(xiě)文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。

1、HashMap

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不是線程安全的。

2、TreeMap

是一個(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。

3.ConcurrentHashMap

在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è)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI