HashMap和HashSet的认识、基本使用

一、HashMap、HashSet认识
二、HashMap、HashTable认识
三、HashMap、HashSet的基本使用
四、HashTable的用法
五、“Usage of API documented as @since 1.8+”报错的解决办法

HashMap、HashSet认识

  • HashSet实现了set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将随想存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现。public boolean add(Object o) 方法用来在Set中添加元素,当元素重复时则会立即返回false,如果添加成功会返回true。
  • HashMap实现了Map接口,Map接口对键值进行映射。Map中不允许重复的键,Map接口有两个基本的实现,HashMap和TreeMap。Tree Map保存了对象的排列次序,而HashMap则不能。Hash Map运行键和值为NULL,HashMap是非synchronized的,但collection框架提供方法保证Hash Map synchronized,这样多个线程同时访问HashMap时,能保证只有一个线程更改Map.
  • public Objecct put(Object key,Object value)方法用来将元素添加到map中。

HashMap和HashSet的区别:

HashMapHashSet
HashMap实现了Map接口Hash Set实现了Set接口
Hash Map存储的时键值对HashMap仅仅存储对象
使用put方法将元素放入map中使用add()方法将元素放入set中
HashMap中使用键对象来计算HashCode值HashSet使用成员对象来计算hashcode的值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false
HashMap比较快,因为是使用唯一的键来获取对象HashSet较HashMap慢一些

HashMap、HashTable认识

HashMap基于hashing原理,我们通过put()和get()方法储存和获取对下个。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,然后找到bucket位置来储存值对象。当你获取对象时,通过键对象的equals方法找到正确的键值时,然后返回值对象。HashMap使用链表来解决碰撞问题,当碰撞发生了,对象会储存在链表的下一个节点中。HashMap在每个链表节点中储存键值对对象。

HashMap和HashTable都实现了Map接口,主要的区别:线程安全性,同步(synchronization),以及速度。

  1. HashMap除了是非synchronized的,并可以接受null的键和值,几乎等价于HashTable
  2. HashMap是非synchronized,而HashTable是synchronized,这意味着Hash Table是线程安全的,多个线程可以共享一个HashTable;而如果没有正确同步的话,多个线程是不能共享HashMap的。java5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
  3. 另一个区别是HashMap的迭代器(iterator)是fail-fast迭代器,而hashTable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和iterator的区别。
  4. 由于HashTable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
  5. HashMap不能保证随着时间的推移Map中的元素次序是不变的
HashMapHashTable
线程不安全线程安全
允许有null的键和值不允许有null的键和值
效率高一点效率稍低
方法不是Synchronize的要提供对外同步方法是Synchronize的
有containsvalue和containsKey方法有contains方法
HashMap是Java1.2引进的Map interface的一个实现HashTable继承于Dictionary类
HashMap是Hashtable的轻量级实现HashTable比HashMap要旧

HashMap、HashSet的基本使用

package JavaSEWY;

import java.util.HashMap;
import java.util.HashSet;

public class hello {
    public static void main(String[] args) {
       HashSet<Integer> hashset = new HashSet<>();
       hashset.add(0);
       hashset.add(1);
       hashset.add(1);
        hashset.add(2);

       //查看hashset的长度
       System.out.println("hashset的长度: " + hashset.size());

       //遍历HashSet中的元素
       for (Integer integer: hashset)
       {
           System.out.println("2 HashSet中的元素如下:" +integer);
       }
       //查看hashSet中是否包含0,返回值为True or False
       System.out.println("HashSet中是否包含4,返回值为:" + hashset.contains(4));

       System.out.println("----我是分割线----");

       HashMap<Integer, Integer> hashmap = new HashMap<>();
       hashmap.put(1,2);
       hashmap.put(3,4);
        hashmap.put(5,6);

        //替换key=2时,value的值更换为4;成功与否的返回值都是True或者False
       System.out.println("replace是否成功替换value的值,返回值为:" + hashmap.replace(2,1,4));
       System.out.println("-------------------");
       //首先查找key,找到了返回key对应的value;找不到返回null
       System.out.println("返回key对应的value"+ hashmap.get(3));
       System.out.println("-------------------");
       System.out.println("HashMap中key的集合:" + hashmap.keySet());
        System.out.println("-------------------");
       System.out.println("HashMap中value的集合:" +hashmap.values());
        System.out.println("-------------------");
       System.out.println("输出HashMap中key=value的集合:"+hashmap.entrySet());
    }

}

运行结果:
hashset的长度: 3
2 HashSet中的元素如下:0
2 HashSet中的元素如下:1
2 HashSet中的元素如下:2
HashSet中是否包含4,返回值为:false
----我是分割线----
replace是否成功替换value的值,返回值为:false
-------------------
返回key对应的value4
-------------------
HashMap中key的集合:[1, 3, 5]
-------------------
HashMap中value的集合:[2, 4, 6]
-------------------
输出HashMap中key=value的集合:[1=2, 3=4, 5=6]

可以自行去HashMap和HashSet中查看对应源码:

  1. hashmap.get(3) ==>定位到源码:
    public V get(Object key) {
    Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
    }
    源码中的解释:
 /**
     * Returns the value to which the specified key is mapped,
     * or {@code null} if this map contains no mapping for the key.
     *
     * <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.)
     *
     * <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.
     *
     * @see #put(Object, Object)
     */

翻译:返回指定键映射到的值
1)、如果此映射不包含键的映射,返回值是null
2)、如果此映射包含一个key,eg: hashmap.put(3,4); 我们使用hashmap.get(3) ==>
取到对应的value值是4;hashmap.get(4) ==> key找不到对应的value,返回值就是null

英语课:explicitly:明确的 distinguish:区分、辨别

Hashtable的用法

需求:把姓名-年龄这样的信息存入一个容器,将来查A多少岁,立刻能出来年龄?

package day0720;

import java.util.Enumeration;
import java.util.Hashtable;

public class HashTableApp {
    public static void main(String[] args) {
        Hashtable hashtable = new Hashtable();
        hashtable.put("one", new Integer(1));
        hashtable.put("two", new Integer(2));
        hashtable.put("three", new Integer(3));
        hashtable.put("four", new Integer(4));

        Integer hashtable1 = (Integer) hashtable.get("twotwo");
        if (hashtable1 != null) {
            System.out.println("won't print = " + hashtable1);
        }

        Integer m = (Integer) hashtable.get("two");
        if (m != null) {
            System.out.println("two:" + m);
        }

        Enumeration e = hashtable.elements();
        while (e.hasMoreElements()) {
            System.out.println(e.nextElement());
        }
        Enumeration ke = hashtable.keys();
        while (ke.hasMoreElements()) {
            System.out.println(ke.nextElement());
        }


    }

输出:
two:2
2
1
3
4
two
one
three
four

“Usage of API documented as @since 1.8+”报错的解决办法

报错信息:
Usage of API documented as @since 1.8+
This inspection finds all usages of methods that have @since tag in their documentation.
This may be useful when development is performed under newer SDK version as the target platform for production.

解决: ctrl+shift+alt+S,修改Language Level为8

在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值