欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java SE 集合:Map接口

程序员文章站 2022-06-09 20:40:23
...

Java SE 集合:Map接口

Values ,HashTable ,CollectionsHashMap 同步

1、Set 接口 hashSet

  • 无序,去重

  • HashSet的底层是用 HashMap 实现的

  • 底层结构: 哈希表(数组+链表+红黑树) 不同步

  • 特点:
      做查询,增删效率较高
      无序去重

  • 初始容量: 16
    加载因子: 0.75 ->扩容的临界点

  • 扩容的临界点 = 容量*加载因子;
      12 = 16*0.75; 当存储的数据到12就扩容

注意:

  HashSet 与 TreeSet之间的选择
  如果想要数据存储的时候默认升序|降序->TreeSet
  否则建议选择HashSet

1.1 构造器

构造器 描述
HashSet() 构造一个新的空集; 支持HashMap实例具有默认初始容量(16)和加载因子(0.75)。
HashSet(int initialCapacity) 构造一个新的空集; 支持HashMap实例具有指定的初始容量和默认加载因子(0.75)。
HashSet(int initialCapacity, float loadFactor) 构造一个新的空集; 支持HashMap实例具有指定的初始容量和指定的加载因子。
HashSet(Collection<? extends E> c) 构造一个包含指定集合中元素的新集合。
//HashSet() 构造一个新的空集; 支持HashMap实例具有默认初始容量(16)和加载因子(0.75)。
 HashSet<String> hs=new HashSet<>();
//HashSet(int initialCapacity) 构造一个新的空集; 支持HashMap实例具有指定的初始容量和默认加载因子(0.75)。
 HashSet<String> hs2=new HashSet<>(20);

1.2 常用方法(一些)

变量和类型 方法 描述
boolean add(E e) 如果指定的元素尚不存在,则将其添加到此集合中。
void clear() 从该集中删除所有元素。
Object clone() 返回此 HashSet实例的浅表副本:未克隆元素本身。
boolean contains(Object o) 如果此set包含指定的元素,则返回 true 。
boolean isEmpty() 如果此集合不包含任何元素,则返回 true 。
Iterator iterator() 返回此set中元素的迭代器。
boolean remove(Object o) 如果存在,则从该集合中移除指定的元素。
int size() 返回此集合中的元素数(基数)。

1.2.1 如何构建存储引用数据类型集合

构建一个HashSet 存储自定义引用数据类型的数据,做基本操作行为,然后遍历
通过HashSet存储自定义引用数据类型的数据去重问题:
需要在自定义引用数据类型中,重写hashcode与equals方法,根据内容计算比较
hashcode 与 equals :
equals相等hashcode值肯定相等
hashcode相等,equals不一定相等
        HashSet<Person> hash = new HashSet<>();
        //默认根据地址做去重
        hash.add(new Person("",18));
        hash.add(new Person("",18));

        System.out.println(hash);
        System.out.println(new Person("",18).hashCode());
        System.out.println(new Person("",18).hashCode());

//HashSet() 构造一个新的空集; 支持HashMap实例具有默认初始容量(16)和加载因子(0.75)。
//HashSet(int initialCapacity) 构造一个新的空集; 支持HashMap实例具有指定的初始容量和默认加载因子(0.75)。
//HashSet(int initialCapacity, float loadFactor) 构造一个新的空集; 支持HashMap实例具有指定的初始容量和指定的加载因子。
//HashSet(Collection<? extends E> c) 构造一个包含指定集合中元素的新集合。
        HashSet<String> hs=new HashSet<>();
        hs.add("aja");


//boolean add(E e) 如果指定的元素尚不存在,则将其添加到此集合中。
    hs.add("gkdlg");
//void clear() 从该集中删除所有元素。

//Object clone() 返回此 HashSet实例的浅表副本:未克隆元素本身。
//boolean contains(Object o) 如果此set包含指定的元素,则返回 true 。
        System.out.println(hs.contains("gkdlg"));
//boolean isEmpty() 如果此集合不包含任何元素,则返回 true 。
        System.out.println(hs.isEmpty());
//Iterator<E> iterator() 返回此set中元素的迭代器。
        //Iterator iterator= hs.iterator();
//boolean remove(Object o) 如果存在,则从该集合中移除指定的元素。
        hs.remove("gkdlg");
//int size() 返回此集合中的元素数(基数)。
        System.out.println( hs.size());
//Spliterator<E> spliterator() 在此集合中的元素上创建late-binding和失败快速 Spliterator 。

1.3 遍历

  //遍历
       for (String s:hs) {
            System.out.println(s);
        }

        //迭代器
        Iterator ia= hs.iterator();
        while(ia.hasNext()){
            System.out.println(ia.next());
        }

2、Map 接口

常见的实现类有 HashMapHashTable

  • Map<K,V>
  • 接口
  • 存储键值对的数据
  • k-v 一个映射关系:key->value;一个key只能对应一个value
  • key与value可以为任意类型的一个数据
  • key是唯一的,无序的 --> Set集合
  • value是无序可重复的 --> Collection 无序可重复

注意:如果存入的键值对中key相同,那么后面的会覆盖掉前面的数据存放到Map之后,我们是无

法控制存放数据的顺序的

2.1、遍历方式:

  • Set< K> keySet() 返回所有的key,通过key获取value
  • Collection< V> values() 获取集合中的所有value值,无法获取key
  • Set<Map.Entry<K,V>> entrySet()
				//多态
				Map<Integer,String> map=new HashMap<>();
				// 遍历
        //Set<K> keySet()  返回所有的key,通过key获取value
        System.out.println("-------- Set<K> keySet()  返回所有的key,通过key获取value-------------");
        Set<Integer> set=map.keySet();
        for (int s:set) {
            System.out.println(s+"-->"+map.get(s));
        }
        //Collection<V> values() 获取集合中的所有value值,无法获取key
        System.out.println("-------- Collection<V> values() 获取集合中的所有value值,无法获取key-------------");
        Collection<String> con=map.values();
        for (String s:con) {
            System.out.println(s);
        }
        //Set<Map.Entry<K,V>> entrySet()
        System.out.println("--------Set<Map,Entry<K,V>> entrySet()-------------");
        Set<Map.Entry<Integer,String>> st=map.entrySet();
        for (Map.Entry <Integer,String > m:st) {
            System.out.println(m);
        }

3、 HashMap

​    HashMap作为Map的实现类,其中的方法都进行了实现,并且定义了可以存储数据的空间,其中使用了

一个叫做 Entry 的内部类,作为数据的存储

  • HashSet --> HashMap 不同步

  • 底层结构:
    哈希表(数组+链表+红黑树)

  • 特点:

    • 存储键值对类型数据
    • 无序,根据key做去重
    • 查询,修改,删除,增加效率较高
  • Hash表存储原理:
    哈希表: Node节点数组,存储节点数据 节点:key,value,hash,next
      1.**put(key,value)**存储键值对类型的数据
    构建一个Node节点对象 new Node(key,value,hash,null)

  • 默认初始容量: 1<<4 16–> 数组长度

  • 加载因子 : 0.75

  • 最大容量… 1<<30

  • 扩容: 新数组的容量为原容量的2倍 newCap = oldCap << 1
    当添加的数据个数>=原数组长度*0.75 的时候,就扩容,扩容的是数组的大小

HashMap存储key如果为自定义引用数据类型:
    key去重的问题 : key类型中要求重写hashcode与equals方法

3.1、构造器

构造器 描述
HashMap() 使用默认初始容量(16)和默认加载因子(0.75)构造一个空 HashMap 。
HashMap(int initialCapacity) 使用指定的初始容量和默认加载因子(0.75)构造一个空 HashMap 。
HashMap(int initialCapacity, float loadFactor) 使用指定的初始容量和加载因子构造一个空 HashMap 。
HashMap(Map<? extends K,? extends V> m) 构造一个新的 HashMap ,其映射与指定的 Map相同。
//HashMap()使用默认初始容量(16)和默认加载因子(0.75)构造一个空 HashMap 。 
Map<Integer,String> map=new HashMap<>();
//HashMap(int initialCapacity,  float loadFactor)使用指定的初始容量和加载因子构造一个空 HashMap 。 
HashMap<Integer,User> hash = new HashMap<>(20,0.8);

3.2、常用方法(一些)

变量和类型 方法 描述
void clear() 从此映射中删除所有映射。
Object clone() 返回此 HashMap实例的浅表副本:未克隆键和值本身。
V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 尝试计算指定键及其当前映射值的映射(如果没有当前映射, null )。
V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) 如果指定的键尚未与值关联(或映射到 null ),则尝试使用给定的映射函数计算其值并将其输入此映射,除非 null 。
V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 如果指定键的值存在且为非null,则尝试在给定键及其当前映射值的情况下计算新映射。
boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true 。
Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射的Set视图。
V get(Object key) 返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。
boolean isEmpty() 如果此映射不包含键 - 值映射,则返回 true 。
Set keySet() 返回此映射中包含的键的Set视图。
V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) 如果指定的键尚未与值关联或与null关联,则将其与给定的非空值关联。
V put(K key, V value) 将指定的值与此映射中的指定键相关联。
void putAll(Map<? extends K,? extends V> m) 将指定映射中的所有映射复制到此映射。
V remove(Object key) 从此映射中删除指定键的映射(如果存在)。
int size() 返回此映射中键 - 值映射的数量。
Collection values() 返回此映射中包含的值的Collection视图。

HashMap存储key如果为自定义引用数据类型:
    key去重的问题 : key类型中要求重写hashcode与equals方法

       Map<Integer,String> map=new HashMap<>();
        //V put(K key, V value) 将指定的值与此映射中的指定键相关联(可选操作)。
        map.put(1001,"haha");
        map.put(1010,"zss");
        map.put(1005,"hjfnks");
        map.put(1002,"vghdjkgv");
        map.put(1004,"sfskl");
        map.put(1012,"dsjkv");

        System.out.println(map);

        // 遍历
        //Set<K> keySet()  返回所有的key,通过key获取value
        System.out.println("-------- Set<K> keySet()  返回所有的key,通过key获取value-------------");
        Set<Integer> set=map.keySet();
        for (int s:set) {
            System.out.println(s+"-->"+map.get(s));
        }
        //Collection<V> values() 获取集合中的所有value值,无法获取key
        System.out.println("-------- Collection<V> values() 获取集合中的所有value值,无法获取key-------------");
        Collection<String> con=map.values();
        for (String s:con) {
            System.out.println(s);
        }
        //Set<Map.Entry<K,V>> entrySet()
        System.out.println("--------Set<Map,Entry<K,V>> entrySet()-------------");
        Set<Map.Entry<Integer,String>> st=map.entrySet();
        for (Map.Entry <Integer,String > m:st) {
            System.out.println(m);
        }

        System.out.println("==================================");
        //V get(Object key)  根据key获取value,没有返回null
        System.out.println(map.get(1005));

        //int size()
        System.out.println(map.size());

        //boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。
        //boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true 。
        System.out.println(map.containsKey(1012)); //true
        System.out.println(map.containsValue("zss"));//true

        //V remove(Object key) 如果存在,则从该映射中移除键的映射(可选操作)。
        System.out.println(map.remove(1021));// nulls

        //default V replace(K key, V value) 仅当指定键当前映射到某个值时,才替换该条目的条目。
        System.out.println(map.remove(1021,"hahd"));//flase

        //default boolean replace(K key, V oldValue, V newValue) 仅当前映射到指定值时,才替换指定键的条目。
        System.out.println(map.replace(1001,"haha","heihei"));//true

4、TreeMap

  • extends AbstractMap<K,V>
  • TreeSet底层就是由TreeMap维护的
  • 底层结构: 红黑树
  • 特点: 有序(默认升序排序),存放存储与内部真实存储顺序是不一致的
  • 此实现不同步
  • 注意: 以后什么功能|结构能够实现排序的,想到比较器:指定比较规则

去重排序: 根据key实现去重与排序
  key中存放的数据的类型->1)实现内部比较器 2)实现外部比较器

TreeMap<Student,String> trst=new TreeMap<>();

存储数据,在存储的时候才会比较,排序
trst.put(new Student(1020,"haha",20,'男'),"大数据");
trst.put(new Student(1002,"dudu",22,'男'),"java");
trst.put(new Student(1001,"cici",21,'男'),"大数据");
trst.put(new Student(1014,"bibi",24,'男'),"html");

map.put(null,null);  //treemap中存储键值对key不能为null
System.out.println(trst);

//外部比较器
TreeMap<Student,String> trst2=new TreeMap<>((o1, o2) -> o1.getName().compareTo(o2.getName()));
    trst2.putAll(trst);

System.out.println(trst2);

5、HashTable

  • 实现了一个哈希表,它将键映射到值。 任何非null对象都可以用作键或值。
  • 初始容量负载因子容量是哈希表中的数, 初始容量只是创建哈希表时的容量。
    • 默认初始容量(11)和加载因子(0.75)
  • extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable
构造器 描述
Hashtable() 使用默认初始容量(11)和加载因子(0.75)构造一个新的空哈希表。
Hashtable(int initialCapacity, float loadFactor) 使用指定的初始容量和指定的加载因子构造一个新的空哈希表。
变量和类型 方法 描述
void clear() 清除此哈希表,使其不包含任何键。
V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 尝试计算指定键及其当前映射值的映射(如果没有当前映射, null )。
boolean contains(Object value) 测试某些键是否映射到此哈希表中的指定值。
boolean containsKey(Object key) 测试指定的对象是否是此哈希表中的键。
boolean containsValue(Object value) 如果此哈希表将一个或多个键映射到此值,则返回true。
Enumeration elements() 返回此哈希表中值的枚举。
Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射的Set视图。
boolean equals(Object o) 根据Map接口中的定义,将指定的Object与此Map进行相等性比较。
V get(Object key) 返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。
int hashCode() 根据Map接口中的定义返回此Map的哈希码值。
boolean isEmpty() 测试此哈希表是否将键映射到值。
Enumeration keys() 返回此哈希表中键的枚举。
Set keySet() 返回此映射中包含的键的Set视图。
V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) 如果指定的键尚未与值关联或与null关联,则将其与给定的非空值关联。
V put(K key, V value) 将指定的 key映射到此哈希表中的指定 value 。
void putAll(Map<? extends K,? extends V> t) 将指定映射中的所有映射复制到此哈希表。
protected void rehash() 增加此哈希表的容量并在内部重新组织,以便更有效地容纳和访问其条目。
V remove(Object key) 从此哈希表中删除键(及其对应的值)。
int size() 返回此哈希表中的键数。
String toString() 以一组条目的形式返回此 Hashtable对象的字符串表示形式,用大括号括起,并用ASCII字符“ , ”(逗号和空格)分隔。
Collection values() 返回此映射中包含的值的Collection视图。

5.2、Properties

    Properties类表示一组持久的属性。 Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。

  • 存储的键值对都为字符串类型
  • Properties类表示一组持久的属性。
  • extends Hashtable<Object,Object>
  • Properties可以保存到流中或从流中加载。

总结:

  • properties作为配置文件使用的步骤:

    • 1.src下新建一个file文件,名字问xx.properties
    • 2.zai配置文件中定义键值对为字符串的数据(注意不加"",;…)
    • 3.程序中定义个Properties对象.通过对象.load(流) 指定从某一个资源文件中读取数据,使用指定的流
    • 4.对象.getProperty(key)
  • properties根式作为配置文件的格式存在,键值对 都是字符串,简单

  • 程序从properties文件中读取数据:
    void load(InputStream inStream) 从输入字节流中读取属性列表(键和元素对)。

5.2.1、构造器

构造器 描述
Properties() 创建一个没有默认值的空属性列表。
Properties(int initialCapacity) 创建一个没有默认值的空属性列表,并且初始大小容纳指定数量的元素,而无需动态调整大小。
Properties(Properties defaults) 创建具有指定默认值的空属性列表。

5.2.2、常用方法

变量和类型 方法 描述
String getProperty(String key) 在此属性列表中搜索具有指定键的属性。
String getProperty(String key, String defaultValue) 在此属性列表中搜索具有指定键的属性。
void list(PrintWriter out) 将此属性列表打印到指定的输出流。
void load(InputStream inStream) 从输入字节流中读取属性列表(键和元素对)。
			Properties ppt=new Properties();

        //新增方法
        ppt.setProperty("123","456");

        //通过properties对象从配置文件中读取数据
        //指定从哪一个文件,通过哪个流加载
        ppt.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("week04/day01/properties02/hhh.properties"));
        System.out.println(ppt.getProperty("name1"));
        System.out.println(ppt.getProperty("sex1"));
        System.out.println(ppt.getProperty("name2"));
        System.out.println(ppt.getProperty("sex2"));
        System.out.println(ppt.getProperty("嘿嘿"));

6、Collections

Collections 与 Collection 之间的区别:

  • Collection 集合体系的上层接口
  • Collections 操作集合数据的工具类 , 与 Arrays很像

常用方法:

  • void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。

  • void shuffle(List) //对List容器内的元素进行随机排列

  • void reverse(List) //对List容器内的元素进行逆续排列

  • void fill(List, Object) //用一个特定的对象重写整个List容器

  • int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象
    使用前提: 升序排序

HashMap线程不安全问题:

  • ​ 1.Hashtable类型,线程安全类型的Map
    • Hashtable是同步的。 如果不需要线程安全实现,建议使用HashMap代替Hashtable 。 如果需要线程安全的高度并发实现,则建议使用ConcurrentHashMap代替Hashtable 。
  • 2.Collections -> static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) 返回由指定映射支持的同步(线程安全)映射。
  • 3.juc包(高级并发编程包) - > ConcurrentHashMap 线程安全的哈希表—>推荐,安全性好效率高
        List<Integer> lt=new ArrayList<>();
        lt.add(23);
        lt.add(34);
        lt.add(56);
        lt.add(86);
        lt.add(1);
        System.out.println(lt);

        //void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。
        Collections.sort(lt);
        System.out.println(lt);
//          void shuffle(List) //对List容器内的元素进行随机排列
        Collections.shuffle(lt);
        System.out.println(lt);
//        void reverse(List) //对List容器内的元素进行逆续排列
        Collections.reverse(lt);
        System.out.println(lt);
//        void fill(List, Object) //用一个特定的对象重写整个List容器
        Collections.fill(lt,56);
        System.out.println(lt);
//        int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象
//            使用前提: 升序排序
        Collections.sort(lt);
        Collections.binarySearch(lt,34);
        System.out.println(lt);

Values ,HashTable ,CollectionsHashMap 同步

相关标签: Java java