Android知识Android技术知识Android开发

大厂Android面试题汇总(三)数据结构

2018-04-28  本文已影响0人  我的天呐0_0
//存储
public V put(K key, V value) {
    // HashMap允许存放null键和null值。
    // 当key为null时,调用putForNullKey方法,将value放置在数组第一个位置。  
    if (key == null)
        return putForNullKey(value);
    // 根据key的keyCode重新计算hash值。
    int hash = hash(key.hashCode());
    // 搜索指定hash值在对应table中的索引。
    int i = indexFor(hash, table.length);
    // 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素。
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    // 如果i索引处的Entry为null,表明此处还没有Entry。
    modCount++;
    // 将key、value添加到i索引处。
    addEntry(hash, key, value, i);
    return null;
}

void addEntry(int hash, K key, V value, int bucketIndex) {
    // 获取指定 bucketIndex 索引处的 Entry  
    Entry<K,V> e = table[bucketIndex];
    // 将新创建的 Entry 放入 bucketIndex 索引处,并让新的 Entry 指向原来的 Entry  
    table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
    // 如果 Map 中的 key-value 对的数量超过了极限
    if (size++ >= threshold)
    // 把 table 对象的长度扩充到原来的2倍。
        resize(2 * table.length);
}

static int hash(int h) {
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);  
}

static int indexFor(int h, int length) {  
    return h & (length-1);
}

//获取
public V get(Object key) {
    if (key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
        e != null;
        e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  
            return e.value;
    }
    return null;
}

简单来说就是将Entry根据hash算法放入数组的链表中的一个过程
详见上

public void depthFirst() {  
    Stack<Map<String, Object>> nodeStack = new Stack<Map<String, Object>>();  
    Map<String, Object> node = new HashMap<String, Object>();  
    nodeStack.add(node);  
    while (!nodeStack.isEmpty()) {  
        node = nodeStack.pop();  
        System.out.println(node);  
        //获得节点的子节点,对于二叉树就是获得节点的左子结点和右子节点  
        List<Map<String, Object>> children = getChildren(node);  
        if (children != null && !children.isEmpty()) {  
            for (Map child : children) {  
                nodeStack.push(child);  
            }  
        }  
    }  
}  
​//节点使用Map存放  
public void breadthFirst() {  
    Deque<Map<String, Object>> nodeDeque = new ArrayDeque<Map<String, Object>>();  
    Map<String, Object> node = new HashMap<String, Object>();  
    nodeDeque.add(node);  
    while (!nodeDeque.isEmpty()) {  
        node = nodeDeque.peekFirst();  
        System.out.println(node);  
        //获得节点的子节点,对于二叉树就是获得节点的左子结点和右子节点  
        List<Map<String, Object>> children = getChildren(node);  
        if (children != null && !children.isEmpty()) {  
            for (Map child : children) {  
                nodeDeque.add(child);  
            }  
        }  
    }  
}  
//这里使用的是双端队列,和使用queue是一样的  

Java遍历树(深度优先+广度优先)

问题来自:AWeiLoveAndroid的博客

上一篇下一篇

猜你喜欢

热点阅读