java学习_5_23

Collection接口中定义的方法如下,所有继承自Collection接口的接口(List,Set)的实现类均实现了这些方法。

List容器是有序、可重复的,常用的实现类:ArrayList,LinkedList,Vector(线程安全的)

索引的add,remove操作。


 自己实现的MyArrayList:

package test.stringTest;

public class MyArrayList<E> {
    private Object[] elementData;
    // 元素个数
    private int size;
    // 数组默认长度
    private final static int DEFAULT_CAPACITY = 10;

    public MyArrayList() {
        elementData = new Object[DEFAULT_CAPACITY];
    }

    public MyArrayList(int length) {
        if (length <= 0)
            throw new RuntimeException("容器容量值需为正整数:" + length);
        elementData = new Object[length];
    }

    public void add(E element) {
        if (size == elementData.length)
            grow();
        elementData[size++] = element;
    }

    @SuppressWarnings("unchecked")
    public E get(int index) {
        if (indexInRange(index))
            return (E) elementData[index];
        else
            throw new RuntimeException("索引越界:" + index);
    }

    public void remove(E element) {
        int index = -1;
        for (int i = 0; i < size; i++) {
            if (element.equals(elementData[i])) {
                index = i;
                break;
            }
        }
        if (index != -1) {
            remove(index);
        }
    }

    public void remove(int index) {
        if (!indexInRange(index)) {
            throw new RuntimeException("索引越界:" + index);
        }
        int numMoved = elementData.length - index - 1;
        if (numMoved > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        } else {
            elementData[index] = null;
        }
        size--;
    }

    private boolean indexInRange(int index) {
        return index < size && index >= 0 ? true : false;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0 ? true : false;
    }

    // 数组扩容
    private void grow() {
        Object[] newArray = new Object[elementData.length + (elementData.length >> 1)];
        System.arraycopy(elementData, 0, newArray, 0, elementData.length);
        elementData = newArray;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(elementData[i].toString() + ",");
        }
        sb.setCharAt(sb.length() - 1, ']');
        return sb.toString();
    }

    public static void main(String[] args) {
        MyArrayList<String> list = new MyArrayList<>(20);
        int i = 0;
        while (i <= 50) {
            list.add("aaa" + i);
            i++;
        }
        System.out.println(list);
        System.out.println(list.get(31));
        System.out.println(list.size());
        list.remove(21);
        list.remove("aaa4");
        System.out.println(list);
        System.out.println(list.size);
        System.out.println(list.isEmpty());
    }
}

HashMap底层实现:数组加链表(JDK8以后当元素个数超过8时,会转变为红黑树结构)。首先根据Key计算出hashcode,然后根据hashcode,利用hash算法计算出数组的下标,然后将值放入该下标数组存储的链表中(有重复(equals比较)的key值则覆盖) 两个相同的对象必须具有相同的hashcode。

    /**
     * The table, initialized on first use, and resized as
     * necessary. When allocated, length is always a power of two.
     * (We also tolerate length zero in some operations to allow
     * bootstrapping mechanics that are currently not needed.)
     */
    transient Node<K,V>[] table;

    /**
     * Basic hash bin node, used for most entries.  (See below for
     * TreeNode subclass, and in LinkedHashMap for its Entry subclass.)
     */
    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }
..........

 自己实现的HashMap:

 1 package test.stringTest;
 2 
 3 public class MyHashMap<K,V> {
 4     Node<K,V>[] table; // 位桶数组
 5     int size;
 6 
 7     public MyHashMap() {
 8         table = new Node[16];
 9     }
10 
11     public void put(K key, V value) {
12         Node<K,V> node = new Node<>();
13         node.key = key;
14         node.value = value;
15         node.next = null;
16         node.hash = myHash(key, table.length);
17         Node<K,V> temp = table[node.hash];
18         Node<K,V> lastNode = temp;
19         boolean isOverride = false; // 有没被覆盖
20         if (temp == null) {
21             table[node.hash] = node;
22             size++;
23         } else {
24             while (temp != null) {
25                 // key相同 则覆盖
26                 if (temp.key.equals(key)) {
27                     temp.value = value;
28                     isOverride = true;
29                     break;
30                 } else {
31                     // 不同 则继续向下遍历
32                     lastNode = temp;
33                     temp = temp.next;
34                 }
35             }
36             // 没有覆盖发生 则将Node添加到后面
37             if (!isOverride) {
38                 lastNode.next = node;
39                 size++;
40             }
41         }
42     }
43 
44     public Object get(Object key) {
45         int hash = myHash(key, table.length);
46         Node<K,V> temp = table[hash];
47         if (temp != null) {
48             while (temp != null) {
49                 if (temp.key.equals(key))
50                     return temp.value;
51                 else
52                     temp = temp.next;
53             }
54         }
55         return null;
56     }
57 
58     @Override
59     public String toString() {
60         StringBuilder sb = new StringBuilder("{");
61         for (int i = 0; i < table.length; i++) {
62             Node<K,V> temp = table[i];
63             while (temp != null) {
64                 sb.append(temp.key + ":" + temp.value + ",");
65                 temp = temp.next;
66             }
67         }
68         sb.setCharAt(sb.length() - 1, '}');
69         return sb.toString();
70     }
71 
72     private int myHash(Object key, int length) {
73         return key.hashCode() % length;
74     }
75 
76     public static void main(String[] args) {
77         MyHashMap<String,Integer> map = new MyHashMap<>();
78         map.put("aaa", 111);
79         map.put("bbb", 222);
80         map.put("ccc", 333);
81         map.put("ddd", 444);
82         map.put("aae", 555);
83         map.put("ccc", 666);
84         map.put("rre", 777);
85         map.put("aaa", 321);
86         System.out.println(map.size);
87         System.out.println(map.get("ccc"));
88     }
89 
90 }
91 
92 class Node<K,V> {
93     int hash;
94     K key;
95     V value;
96     Node<K,V> next;
97 }
View Code
原文地址:https://www.cnblogs.com/ustc-anmin/p/10911101.html