HashMap-----get(key)、containsKey(key)

本文基于JDK1.8

1. 注释翻译
    /**
     * Returns the value to which the specified key is mapped,
     * or {@code null} if this map contains no mapping for the key.
     * 返回指定的key映射的值value,如果此映射不包含key键的一射,则返回null。
     * <p>More formally, if this map contains a mapping from a key
     * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
     * key.equals(k))}, then this method returns {@code v}; otherwise
     * it returns {@code null}.  (There can be at most one such mapping.)
     * 更正式的说,如果此映射包含从键key到值value的映射,那么执行(key==null ? k==null :
     * key.equals(k))操作,然后此方法返回返回值value,否则返回null。(最多可以有一个这样的映射。)
     * <p>A return value of {@code null} does not <i>necessarily</i>
     * indicate that the map contains no mapping for the key; it's also
     * possible that the map explicitly maps the key to {@code null}.
     * The {@link #containsKey containsKey} operation may be used to
     * distinguish these two cases.
     * 返回null不代表地图中不包含该key键的映射;有可能这个地图中,将key键映射的值value为null。containsKey操作可用于区分这两种情况。
     *
     * @see #put(Object, Object)
     */

  从上面的注释我们大概的了解到了,get()方法的作用查找哈希表中对应key键的value值,如果所对应的key键在map中有映射的value值,则返回value值,否则返回null。
  当get()方法返回为null时,有一个特殊的情况,那就是key映射到map中的value值本身就为空。在本方法中无法区分它们,但是在containsKey方法中可以区分它们。

2. 源码剖析
	 public V get(Object key) {
        Node<K,V> e;
        // 在这里执行getNode操作,要了解这里的具体操作我们需要先看一下getNode方法,我们在下面分析一下这个方法。
        return (e = getNode(hash(key), key)) == null ? null : e.value;
    }

getNode方法

	/**
     * Implements Map.get and related methods
     * 实现Map.get和相关方法
     * @param hash hash for key
     * @param key the key
     * @return the node, or null if none
     */
    final Node<K,V> getNode(int hash, Object key) {
        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
        // 哈希表已经初始化,且分的桶的头节点不为空
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {
            // 要查找结点的key值等于桶中头节点的key值,直接返回头节点
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                return first;
            // 判断桶中是否有其他结点,进行痛的遍历
            if ((e = first.next) != null) {
            	// 若桶中元素已经树化,使用树的方式查找结点
                if (first instanceof TreeNode)
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                // 还未树化,使用链表的方式(循环遍历链表)进行查找结点
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        return e;
                } while ((e = e.next) != null);
            }
        }
        // 哈希表为空,或桶为空
        return null;
    }

  我们通过源码分析可以发现,get()方法的核心是调用了getNode()方法,getNode()方法,返回了key键所在的结点,如果没有则返回null,get()方法对该值进行判断,然后取出value进行操作。

3. get()执行流程
  1. 若哈希表已经初始化并且桶的首结点不为空
     ① 查找结点的key值恰好等于首结点的key值,直接返回首结点。
     ② 进行桶中元素的遍历,查找指定结点
      a. 若树化,按照树的方法查找指定结点
      b. 按照链表方式查找
  2. 哈希表为空或桶的首结点为null,直接返回null。
4. containsKey(Object key)
	/**
     * Returns <tt>true</tt> if this map contains a mapping for the
     * specified key.
     * 如果此映射包含指定key键的映射,则返回true
     *
     * @param   key   The key whose presence in this map is to be tested
     * @return <tt>true</tt> if this map contains a mapping for the specified
     * key.
     */
    public boolean containsKey(Object key) {
        return getNode(hash(key), key) != null;
    }

  该方法也是调用了getNode方法,在这里方法的作用时,判断该key值在map中是否含有映射关系,如果含有映射关系,则返回true,狗则返回false。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Aho-Corasick算法是一种高效的字符串匹配算法,它可以在一次扫描文本的过程中同时查找多个模式串。该算法通过将模式串预处理为确定有限状态自动机,从而实现快速的匹配过程。与其他算法相比,Aho-Corasick算法的时间复杂度为O(n),与模式串的数量和长度无关。 以下是Aho-Corasick算法的一种Java实现示例: ```java import java.util.*; class AhoCorasick { static class Node { Map<Character, Node> children; Node fail; List<String> outputs; Node() { children = new HashMap<>(); fail = null; outputs = new ArrayList<>(); } } static void buildTrie(Node root, List<String> patterns) { for (String pattern : patterns) { Node curr = root; for (char c : pattern.toCharArray()) { curr.children.putIfAbsent(c, new Node()); curr = curr.children.get(c); } curr.outputs.add(pattern); } } static void buildFailure(Node root) { Queue<Node> queue = new LinkedList<>(); for (Node child : root.children.values()) { child.fail = root; queue.add(child); } while (!queue.isEmpty()) { Node curr = queue.poll(); for (Map.Entry<Character, Node> entry : curr.children.entrySet()) { char c = entry.getKey(); Node child = entry.getValue(); queue.add(child); Node failNode = curr.fail; while (failNode != null && !failNode.children.containsKey(c)) { failNode = failNode.fail; } child.fail = failNode != null ? failNode.children.get(c) : root; child.outputs.addAll(child.fail.outputs); } } } static List<String> search(Node root, String text) { List<String> matches = new ArrayList<>(); Node curr = root; for (char c : text.toCharArray()) { while (curr != null && !curr.children.containsKey(c)) { curr = curr.fail; } curr = curr != null ? curr.children.get(c) : root; for (String output : curr.outputs) { matches.add(output); } } return matches; } public static void main(String[] args) { List<String> patterns = Arrays.asList("he", "she", "his", "hers"); String text = "ushers"; Node root = new Node(); buildTrie(root, patterns); buildFailure(root); List<String> matches = search(root, text); System.out.println(matches); // 输出:[she, he, hers] } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值