【Java】(二十二)Map接口与实现类(HashMap、TreeMap),Collections工具类

Java集合最后一小节。
前两节:
【Java】(二十)Java集合框架,Collection接口,List接口与实现类(ArrayList、Vector、LinkedList)
【Java】(二十一)泛型类/接口/方法/集合,Set接口与实现类(HashSet、TreeSet)

6 Map接口与实现类

在这里插入图片描述

  1. Map接口的特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复。
  2. 集合创建:HashMap<键值数据类型, 值数据类型> 集合名 = new HashMap<>();
  3. 方法:
    (1)添加对象
    v put(K key,v value)//将对象存入到集合中,关联键值。key重复则覆盖原值。
    (2)删除对象:remove()
    (3)获取对象(+增强for循环→遍历)
    Set<String> keys = map1.keySet();//返回一个set集合包含所有的键值
    map集合名.get(键值)//根据键获取对应的值。
    map集合名.entrySet()//键值匹配的Set集合。getKey()getValue()分别获取键值。
    Collection<V> values()//返回包含所有值的Collection集合。
    (4)判断:containsKey()containsValue()
package map;

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

public class mapText {
    public static void main(String[] args) {
        //创建Map集合
        HashMap<String, Integer> map1 = new HashMap<>();

        System.out.println("1.添加元素");
        map1.put("Nike", 1000);
        map1.put("Lining", 100);
        map1.put("Adidas", 500);
        map1.put("Nike", 999);//重复键,值覆盖
        System.out.println(map1.size());
        System.out.println(map1);

        System.out.println("2.删除元素");
        map1.remove("Lining");//根据键值删除
        System.out.println(map1);

        //遍历
        System.out.println("3.1通过keySet()获取键值");
        Set<String> keys = map1.keySet();//返回一个set集合包含所有的键
        for (String key : keys) {
            System.out.println("{"+key+","+map1.get(key)+"}");//获取键对应的值
        }
        System.out.println("3.2通过entrySet()获取<键,值>");
        for (Map.Entry<String, Integer> stringIntegerEntry : map1.entrySet()) {
            System.out.println("{"+stringIntegerEntry.getKey()+","+stringIntegerEntry.getValue()+"}");
        }

        System.out.println("4.查询");
        System.out.println(map1.containsKey("Nike"));
        System.out.println(map1.containsValue(500));
    }
}

/*
1.添加元素
3
{Nike=999, Lining=100, Adidas=500}
2.删除元素
{Nike=999, Adidas=500}
3.1通过keySet()获取键值
{Nike,999}
{Adidas,500}
3.2通过entrySet()获取<键,值>
{Nike,999}
{Adidas,500}
4.查询
true
true
 */

6.1 Map集合的实现类

  • HashMap【重点】:JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value。
  • Hashtable:JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。
  • Properties:Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。
  • TreeMap:实现了SortedMap接口(是Map的子接口),可以对key自动排序

6.2 HashMap类

  1. 存储结构:哈希表(数组+链表+红黑树)
    和之前说过的HashSet类似,判断重复依据是hashCode和equals方法,重写即可。【重写之后才能通过new关键字插入或删除集合中相应的对象】
  2. 查看HashMap的源码分析总结:
    (1)HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16。
    (2)当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
    (3)jdk1.8当每个链表长度>8,并且数组元素个数≥64时,会调整成红黑树,目的是提高效率
    (4)jdk1.8当链表长度<6时调整成链表
    (5)jdk1.8以前,链表时头插入,之后为尾插入
  3. HashSet的存储结构就是HashMap。它的add方法调用的就是map的put方法,把元素作为map的key传进去。

一篇写的很好的HashMap源码分析:HashMap源码分析
默认初始化容量:static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16(算术左移)
数组最大容量:static final int MAXIMUM_CAPACITY = 1 << 30;
默认加载因子:static final float DEFAULT_LOAD_FACTOR = 0.75f;

新建Student类:

package map;

import java.util.Objects;

public class Student {
    String name;
    int number;

    public Student() {
    }

    public Student(String name, int number) {
        this.name = name;
        this.number = number;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", number=" + number +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return number == student.number && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, number);
    }
}

使用Student类作为键的HashMap集合:

package map;

import java.util.HashMap;

public class HashMapText {
    public static void main(String[] args) {
        //创建集合
        HashMap<Student, Integer> map = new HashMap<>();
        //创建student对象
        Student s1 = new Student("a11", 2323);
        Student s2 = new Student("a12", 2345);
        Student s3 = new Student("a13", 2354);

        System.out.println("向集合中添加对象");
        map.put(s1, 22);
        map.put(s2, 18);
        map.put(s3, 20);
        map.put(new Student("a12", 2345), 3);//添加重复键,更新值
        System.out.println(map);

        //删除,遍历,查询和Map一致(不写了)
    }
}
/*
向集合中添加对象
{Student{name='a12', number=2345}=3, Student{name='a13', number=2354}=20, Student{name='a11', number=2323}=22}
 */

6.3 TreeMap类

  1. 实现了SortedMap接口(是Map的子接口),可以对key自动排序。
  2. 存储结构:红黑树
    同样类似TreeSet类,在对象类中实现Comparable接口;或者使用比较器来定制比较。
  3. TreeSet的存储结构实际上就是TreeMap。它的add方法调用的就是TreeMap的put方法,将元素作为key传入到存储结构中。

7 Collections工具类

  1. 概念:集合工具类,定义了除了存取以外的集合常用方法。
  2. 方法:
    public static void reverse(List<?> list)//反转集合中元素的顺序
    public static void shuffle(List<?> list)//随机重置集合元素的顺序
    public static void sort(List<T> list)//升序排序(元素类型必须实现Comparable接口)
package map;

import java.util.*;

public class UseCollections {
    public static void main(String[] args) {
        ArrayList<Integer> listset = new ArrayList<>();
        listset.add(100);
        listset.add(34);
        listset.add(25);
        listset.add(33);
        System.out.println("原始集合ArrayList:"+listset);

        Collections.sort(listset);
        System.out.println("排序集合ArrayList:"+listset);

        int i = Collections.binarySearch(listset, 33);
        System.out.println("二分查找33的序列号:"+i);

        ArrayList<Integer> list2 = new ArrayList<>();
        for (int i1 = 0; i1 < listset.size(); i1++) {//开辟空间
            list2.add(0);
        }
        Collections.copy(list2, listset);
        System.out.println("复制集合list2:"+list2);

        Collections.reverse(list2);
        System.out.println("反转后序列:"+list2);

        Collections.shuffle(list2);
        System.out.println("打乱:"+list2);

        //list转成数组
        Integer[] arr=list2.toArray(new Integer[0]);
        System.out.println(arr.length);
        //数组转成集合
        String[] nameStrings= {"LU","MA","YANG"};
        List<String> list3 = Arrays.asList(nameStrings);//受限集合,不能添加和删除
//        list3.add("aa");//编译报错
        System.out.println(list3);
    }
}
/*
原始集合ArrayList:[100, 34, 25, 33]
排序集合ArrayList:[25, 33, 34, 100]
二分查找33的序列号:1
复制集合list2:[25, 33, 34, 100]
反转后序列:[100, 34, 33, 25]
打乱:[33, 34, 100, 25]
4
[LU, MA, YANG]
*/
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值