Java笔记之集合(二十一)

一、Map 接口☆

1.基本介绍

Map 接口的关系图在这里插入图片描述
Map 接口特点

  1. Map与Collection并列存在,用于保存具有映射关系的数据:Key-value键值对的形式
  2. Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node(静态内部类)对象中
  3. Map中的key不允许重复,Value可以重复,如果添加相同的key,则会替换掉原来的
  4. Map中的key可以是null,value也可以为null,key中的null只能有一个
  5. 常用String类作为Map的key
  6. key和value之间存在单向一对一关系,即通过key总能找到对应的value
  7. Map存放数据的key-value示意图,一对k-v是放在一个Node中的,因为Node实现了Entry接口,所以一对k-v就是一个Entry

通过实现类HashMap测试

import java.util.HashMap;
import java.util.Map;

class test1{
    @SuppressWarnings({"all"})
    public static void main(String[] args){
        //特点1
        Map map = new HashMap();
        map.put(1,"tom");   //键值对
        map.put(2,"juck");
        System.out.println(map);    //{1=tom, 2=juck}

        //特点3
        map.put(1,"小明");
        System.out.println(map);    //{1=小明, 2=juck}

        //特点4
        map.put(null,null);
        System.out.println(map);    //{null=null, 1=小明, 2=juck}

        //特点5
        map.put("java",1);
        map.put(new String("python"),2);
        System.out.println(map);   //{null=null, 1=小明, 2=juck, python=2, java=1}

        //特点6
        System.out.println(map.get("java"));    //1
        System.out.println(map.get(1)); //小明
        System.out.println(map.get("python"));  //2
    }
}

2.常用方法

方法名功能
put添加
remove删除
get根据键获取值
size获取元素个数
isEmpty判断个数是否为0
clear清除元素
containsKey查找键是否存在

3.遍历方法

  • values():方法时获取集合中的所有的值
  • KeySet():将Map中所有的键存入到set集合,KeySet只能通过get()获取key
  • entrySet():Set<Map.Entry<K,V>> entrySet() //返回此映射中包含的映射关系的Set视图。Map.Entry表示映射关系。entrySet()取key,e.getValue()取value,返回的是Entry接口

“keySet是key的集合,Set…keySet()的速度比entrySet()慢了很多,使用entrySet则必须将map对象转换为Map.Entry,keySet则不需要。也就是keySet方式遍历Map的性能不如entrySet性能好 为了提高性能,以后多考虑用entry”

import java.util.*;

class test1{
    @SuppressWarnings({"all"})
    public static void main(String[] args){
        Map map = new HashMap();
        map.put(1,"java");
        map.put(2,"scala");
        map.put(3,"python");
        map.put(4,"php");

        //第一组把所有key取出,通过key取出对应的value
        Set keySet = map.keySet();
        //方式一:增强for
        System.out.println("方式一");
        for (Object key : keySet) {
            System.out.println(key+"-"+map.get(key));
        }

        //方式二:迭代器
        System.out.println("方式二");
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()){
            Object key = iterator.next();
            System.out.println(key+"-"+map.get(key));
        }

        //第二组:把所有的value取出来
        Collection values = map.values();
        //方式三:增强for
        System.out.println("方式三");
        for (Object value:values) {
            System.out.println(value);
        }

        //方式四:迭代器
        System.out.println("方式四");
        Iterator iterator1 = values.iterator();
        while (iterator1.hasNext()){
            Object value = iterator1.next();
            System.out.println(value);
        }

        //第三组: 通过 EntrySet 来获取 k-v
        Set entrySet = map.entrySet();// EntrySet<Map.Entry<K,V>>
        //方式五:增强for
        System.out.println("方式五");
        for (Object entry:entrySet) {
            //将 entry 转成 Map.Entry
            Map.Entry entry1 = (Map.Entry) entry;   //向下转型
            System.out.println(entry1.getKey()+"-"+entry1.getValue());
        }

        //方式六:迭代器
        System.out.println("方式六");
        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()){
            Object entry = iterator2.next();
            Map.Entry entry2 = (Map.Entry) entry;   //向下转型
            System.out.println(entry2.getKey()+"-"+entry2.getValue());
        }
    }
}

二、HashMap

基本介绍
在这里插入图片描述

  1. HashMap是Map接口使用频率最高的实现类
  2. HashMap是以k-v对的方式来存储数据
  3. key不能重复,但是值可以重复,允许使用null键和null值
  4. 如果添加相同的key,则会覆盖原来的key-value,即key保持不变,直接把value值修改了
  5. 与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的
  6. HashMap没有实现同步,因此是线程不安全的

底层机制解析

  1. HashMap底层维护了Node类型的数组table,默认为null
  2. 当创建对象时,将加载因子loadFactor初始化为0.75
  3. 当添加键值对时,通过key的哈希值得到在table的索引值。然后判断是否有元素,如果没有直接添加;如果该索引处有元素,继续判断该元素的key是否和准备加入的key相等,如果相等,则直接替换value值,如果不相等,需要判断是树结构还是链表结构,做出相应的处理。如果添加时发现容量不够,则需要扩容。

底层扩容机制

扩容机制跟HashSet完全相同,因为HashSet底层是new HashMap

  1. 第一次添加是,table数组扩容到16,临界值是threshold为12,threshold=加载因子loadFactor为0.75*16=12
  2. 如果table数组使用到了临界值12,就会扩容到162 = 32,新的临界值= 320.75 = 24;以此类推
  3. 在java1.8中,如果一条链表的元素个数TREEIFY_THRESHOLD到达默认值8,索引大小MIN_TREEIFY_CAPACITY超过默认值64;则就会树化(红黑树)

三、Hashtable

基本介绍
在这里插入图片描述

  1. 存放元素是键值对
  2. Hashtable的k-v都不能为null,否则会抛出异常
  3. Hashtable使用方法和HashMap一样
  4. Hashtable是线程安全

1.Hashtable和HashMap对比

版本线程安全(同步)效率k-v允许null
HashMap1.2不安全可以
Hashtable1.0安全较低不可以

四、Properties

基本介绍
在这里插入图片描述

  1. 存放元素是键值对
  2. 使用特点跟Hashtable类似
  3. Properties可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改

xxx.properties文件常作为配置文件

五、开发中如何选择集合实现类☆

在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特点选择,分析如下:

(1)先判断存储类型(一组对象[底层维护了一个双向链表])
(2)一组对象[单列]:Collection接口
  允许重复:List
      增删多:LinkedList[底层维护了一个双向链表]
      改查多:AaaryList[底层维护Object类型的可变数组]
  不允许重复:Set
      无序:HashSet[底层是HashMap,维护了一个哈希表 即(数组+链表+红黑树)]
      排序:TreeSet
      插入和取出顺序一致:LinkedHashSet,维护数组+双向链表
(3)一组键值对[双列]:Map
  键无序:HashMap [底层是哈希表 即(数组+链表+红黑树)]
  键排序:TreeMap
  键插入和取出顺序一致:LinkedHashMap
  读取文件:Properties

  1. 先判断存储类型(一组对象[底层维护了一个双向链表])
  2. 一组对象[单列]:Collection接口

六、Collections工具类

基本介绍
Collections是一个操作Set、List和Map等集合的工具类,提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,具体方法可以查看API

1.常用静态方法

方法名功能
reverse反转List中元素的顺序
shuffle对List集合元素进行随机排序,每次排序都不同
sort根据元素的自然顺序对指定的List集合元素按升序排序
sort(List,Comparator)根据指定的Comparator产生的顺序 对List集合元素进行排序
swap(List,int i,int j)将指定list集合中的i处元素和j处元素进行交换
max根据元素的自然顺序,返回给定集合中的最大元素
max(Collection,Comparator)根据Comparator指定顺序
min跟max同理
frequency返回指定集合中指定元素出现的次数
replaceAll(List list,Object oldVal,Object newVal)使用新值替换List对象的所有旧值

Comparator是一个匿名内部类,重写compare方法,在方法中编写自己需求的逻辑

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class test1{
    @SuppressWarnings({"all"})
    public static void main(String[] args){
        System.out.println("-----list1-----");
        ArrayList list1 = new ArrayList();
        list1.add(5);
        list1.add(6);
        list1.add(1);
        list1.add(9);
        list1.add(6);
        System.out.println(list1);   //[5, 6, 1, 9, 6]

        //reverse
        Collections.reverse(list1);
        System.out.println(list1);   //[6, 9, 1, 6, 5]

        //shuffle
        Collections.shuffle(list1);  //每次排序都不同
        System.out.println(list1);

        //sort
        Collections.sort(list1);
        System.out.println(list1);   //[1, 5, 6, 6, 9]

        //sort(List,Comparator)
        Collections.sort(list1, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return (int)o2-(int)o1;     //进行一个从大到小的排序
            }
        });
        System.out.println(list1);  //[9, 6, 6, 5, 1]
        
        System.out.println("-----list2-----");
        ArrayList list2 = new ArrayList();
        list2.add("java");
        list2.add("python");
        list2.add("php");
        list2.add("php");
        System.out.println(list2);  //[java, python, php, php]

        //swap
        Collections.swap(list2,1,2);
        System.out.println(list2);  //[java, php, python, php]

        //max() //默认按照字符串长度取最大值
        System.out.println(Collections.max(list2)); //python

        //frequency
        System.out.println(Collections.frequency(list2,"php")); //2

        //replaceAll(List list,Object oldVal,Object newVal)
        Collections.replaceAll(list2,"php","scala");
        System.out.println(list2);  //[java, scala, python, scala]
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王博1999

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值