千家信息网

java集合的实现代码怎么写

发表于:2025-01-22 作者:千家信息网编辑
千家信息网最后更新 2025年01月22日,这篇文章主要介绍了java集合的实现代码怎么写的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java集合的实现代码怎么写文章都会有所收获,下面我们一起来看看吧。1、Has
千家信息网最后更新 2025年01月22日java集合的实现代码怎么写

这篇文章主要介绍了java集合的实现代码怎么写的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java集合的实现代码怎么写文章都会有所收获,下面我们一起来看看吧。

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(Mapm) :把指定集合添加集合中        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);        // 说明,当key相同时,后面的值会覆盖前面的值。        // default V replace(K key, V value) :根据key来替换值,而不做增加操作        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) :根据指定key删除集合中对应的值        Object c = map.remove("c");        System.out.println(c);        System.out.println(map);        // default boolean remove(Object key, Objectvalue) :根据key和value进行删除        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() :返回集合的元素个数        int size = map.size();        System.out.println(size);        // V get(Object key) :根据Key获取值,如果找到就返回对应的值,否则返回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) :根据Key获取值,如果key不存在,则返回默认值        val = map.getOrDefault("a1", "hello");        System.out.println(val);        // Collection values() :返回集合中所有的Value        Collection values = map.values();        for (Object value : values) {            System.out.println(value);        }        // Set keySet() :返回集合中所有的Key        Set set = map.keySet();        for (Object o : set) {            System.out.println(o);        }    }    // 迭代元素    public void testIterator() {        // 第一种:通过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循环        for (Object key : map.keySet()) {            System.out.println(key + "=" +                               map.get(key));        }        System.out.println("------------------------ ");        // 第三种:使用Map接口中的内部类来完成,在框架中大量使用        Set entrySet = map.entrySet();        for (Object obj : entrySet) {            Map.Entry entry = (Map.Entry) obj;            System.out.println(entry.getKey() + "=" +                               entry.getValue());        }    }}

说明:在HashMap中键-值允许为空,但键唯一,值可重复。hashMap不是线程安全的。

2、TreeMap

是一个有序的集合,默认使用的是自然排序方式。

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 +            '}';    }}

测试

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);    }}

说明:从上面的代码可以发现,TreeMap的使用和TreeSet的使用非常相似,观察HashSet集合的源代码可以看出,当创建 HashSet集合时,其实是底层使用的是HashMap。

public HashSet() {        map = new HashMap<>();}

HashSet实际上存的是HashMap的Key。

3.ConcurrentHashMap

在Map集合中我们介绍了HashMapTreeMap,在多线程的情况下这些集合都不是线程安全的,因此可能出现线程安全的问题。

在Java中Hashtable是一种线程安全的HashMapHashtable在方法上与HashMap并无区别,仅仅只是在方法使用了synchronized以此来达到线程安全的目的,我们观察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源码,可以看出它仅仅只是在方法上添加了锁,这大大降低了线程的执行效率,以牺牲效率的形式来达到目的,这显然不是我们在实际中想要的,因此我们需要一种既能在线程安全方面有保障,在效率上还可以的方法。

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[] tab = table;;) {            Node 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(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 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 pred = e;                                if ((e = e.next) == null) {                                    pred.next = new Node(hash, key,                                                              value, null);                                    break;                                }                            }                        }                        else if (f instanceof TreeBin) {                            Node p;                            binCount = 2;                            if ((p = ((TreeBin)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仅仅是在当有线程去操作当前数据的时候添加了锁,因此效率大大提高了。

在线程安全的情况下提高了效率。

关于"java集合的实现代码怎么写"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"java集合的实现代码怎么写"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

0