java基础 之 集合与栈的使用(三)

前文回顾:
戳这里 → java基础 之 集合与栈的使用(一)
戳这里 → java基础 之 集合与栈的使用(二)

阅读指南:第一遍可以先忽略代码~
代码可以直接复制粘贴~

在这里插入图片描述

Map接口

(一)实现类:HashMap
特点
  • HashMap底层是链表+数组,jdk8以加入了红黑树
  • HashMap存储是key-valuel类型的数据
  • key不允许重复(重复时会被覆盖),value值允许重复
  • 数据存储无序
  • key和value都允许为空,但是只能有一个空的key
  • 线程不安全
HashMap集合的一些方法
import java.util.HashMap;

public class TestHashMap {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap<>();
        HashMap newHashMap = new HashMap<>();
        // .put(K V value) 将键(key)/值(value)映射存放到Map集合中,无返回值
        hashMap.put("hello",123);
        hashMap.put("world",234);
        hashMap.put("Hello",123);
        hashMap.put("hello",123);
        newHashMap.put("aaa","111111");
        newHashMap.put("bbb","222222");
        newHashMap.put("ccc","3333333");

        // .get(Object key) 返回指定键所映射的值,没有该key对应的值则返回null,即获取key对应的value。
        System.out.println(hashMap.get("hello"));  // 输出:123
        System.out.println(hashMap.get("hello1"));  // 输出:null
        // . size() 返回Map集合中数据数量,准确说是返回key-value的组数。
        System.out.println(hashMap.size());     // 输出:3
        // isEmpty () 判断Map集合中是否有数据,如果没有则返回true,否则返回false
        System.out.println(hashMap.isEmpty());     // 输出:false
        // remove(Object key) 删除Map集合中键为key的数据并返回其所对应value值。
        hashMap.remove("hello");  // 无返回值
        System.out.println("------");
        // containsKey(Object key) Hashmap判断是否含有key
        System.out.println(hashMap.containsKey("hello"));  // 输出:false
        // containsValue(Object value) Hashmap判断是否含有value:
        System.out.println(hashMap.containsValue(123));  // 输出:true
        // Hashmap添加另一个同一类型的map下的所有数据
        hashMap.putAll(newHashMap);  // 无返回数
        System.out.println(hashMap);
        // Hashmap替换这个key的value
        System.out.println(hashMap.put("aaa","aaa0000"));  // 替换后返回被替换的值
        System.out.println(hashMap);
        // clear() 清空Map集合'
        hashMap.clear();  // 无返回值
    }
}

多说几句:

1、key只能使用基本数据类型(int,char…)的封装类(Integer,String…)
2、jdk1.8 之前 HashMap 由 数组 + 链表 组成,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突。
3、jdk1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(一般为 8 )并且当前数组的长度大于 64 时,此时此索引位置上的所有数据改为使用红黑树存储。
4、插入、查找和删除操作的平均时间复杂度是O(1),但在最坏情况下可能会达到O(n)。

(二)实现类: TreeMap
特点
  • TreeMap是有序的key-value集合,是通过红黑树来实现的

  • 无序(元素顺序与添加顺序不一致),且不允许重复

  • TreeMap的key是有序的

  • 默认会对键进行排序,所以必须实现自然排序和定制排序中的一种

    自然排序:TreeMap的所有key必须实现Comparable接口,且所有的key应该是同一类的对象,否则会抛出ClassCastException(类转换异常)

    定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。此时不需要key实现Comparable接口

  • 若使用自定义类作为key,所属的类需重写equals()和hashCode(),当equals()的返回为true时,compareTo()返回应为0

  • 同一个TreeMap对象中添加的key必须是相同的类型(因为要求key是具有可比性的对象)

【自然排序】代码
// 创建一个Student类,包含name(姓名)、age(年龄)和sno(学号)三个属性
public class Student implements Comparable{
    String name;  // 姓名
    Integer age;  // 年龄
    String sno;   // 学号
    // 构造函数
    public Student(String name, Integer age, String sno) {
        this.name = name;
        this.age = age;
        this.sno = sno;
    }
    // 重写compareto方法。
    @Override
    public int compareTo(Object o) {
        if(o instanceof Student){
            Student s = (Student) o;
            int c_name= this.name.compareTo(s.name);
            int c_sno = this.sno.compareTo(s.sno);
            if(c_name!=0){  // 先按照名称排序
                return this.sno.compareTo(s.name);
            }else if(c_sno!=0){  // 名称相同按照学号排序
                return this.sno.compareTo(s.sno);
            }else { // 名称、学号相同,按照年龄排序
                return this.age.compareTo(s.age);
            }
        }
        return 0;
    }
    // 方便打印显示
    @Override
    public String toString() {
        return "Student{" +"name='" + name + '\'' +", age=" + age +", sno='" + sno + '\'' +'}';
    }
}
import java.util.TreeMap;
public class TestHashMap {
    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap();
        treeMap.put(new Student("xiaoming",23,"1233456"),1234);
        treeMap.put(new Student("xiaoming",23,"1233451"),1234);
        treeMap.put(new Student("xiaoa",12,"1233451"),1234);
        System.out.println(treeMap);
    }
}
-------------打印结果----------------
{Student{name='xiaoa', age=12, sno='1233451'}=1234, Student{name='xiaoming', age=23, sno='1233451'}=1234, Student{name='xiaoming', age=23, sno='1233456'}=1234}
【定制排序】代码
// 创建一个Person类,注意该类不需要实现Comperator接口
import java.util.Comparator;

public class Person{
    String name;  // 姓名
    Integer age;  // 年龄
    String phone; // 性别

    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public Integer getAge() {return age;}
    public void setAge(Integer age) {this.age = age;}
    public String getPhone() {return phone;}
    public void setPhone(String sex) {this.phone = phone;}

    public static final Comparator<Person> COMPARATOR = new Comparator<Person>() {
        @Override
        public int compare(Person o1, Person o2) {
            int p_name= o1.getName().compareTo(o2.getName());  // 按姓名比较
            int p_age = o1.getAge().compareTo(o2.getAge());   // 按年龄
            int p_phone = o1.getPhone().compareTo(o2.getPhone());   // 按手机号比较
            if(p_name!=0){  // 先按照名称排序
                return p_name;
            }else if(p_age!=0){  // 名称相同按照年龄
                return p_age;
            }else { // 名称、年龄相同,按照手机号码排序
                return p_phone;
            }
        }
    };
    public Person(String name, Integer age, String phone) {
        this.name = name;
        this.age = age;
        this.phone = phone;
    }
    @Override
    public String toString() {
        return "Person{" +"name='" + name + '\'' +", age=" + age +", phone='" + phone + '\'' +'}';
    }
}
import java.util.TreeMap;

public class TestHashMap {
    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap(Person.COMPARATOR);
        treeMap.put(new Person("xiaoming",23,"1233456"),1234);
        treeMap.put(new Person("xiaoming",23,"1233451"),1234);
        treeMap.put(new Person("xiaoa",12,"1233451"),1234);
        System.out.println(treeMap);
    }
}
-------打印结果?自己敲或者复制代码自己运行吧,在此偷个懒了.....

1、自然排序需要实现Comparable接口并重写compareTo方法,不需要写get()和set()方法
2、定制排序不需要实现Comparable接口,需要通过匿名内部类生成一个静态常量COMPARATOR、getter()、setter()方法。同时在生成TreeMap对象时,需要使用创建的
COMPARATOR。

TreeMap集合的一些方法
public class TestHashMap {
    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap(Person.COMPARATOR);
        Person p1 = new Person("xiaoming",23,"1233455");
        Person p2 = new Person("xiaoming",23,"1233451");
        treeMap.put(p1,1234);
        treeMap.put(p2,1234);
        treeMap.put(new Person("xiaoa",12,"1233454"),1234);
        Person p4 = new Person("xiaoz",12,"1233452");
        treeMap.put(p4,1234);
        treeMap.put(new Person("xiaoy",22,"1233453"),1234);
        Person example = new Person("xiaon",23,"1233456");
        
        
        // 返回指定的Key大于或等于的最小值的元素,如果没有,则返回null
        Entry K = treeMap.ceilingEntry(example);
        // 返回小于等于key的最大Key的元素
        Entry big = treeMap.floorEntry(example);
        // 返回指定的Key大于或等于的最小值的Key,如果没有,则返回null
        Object obj = treeMap.ceilingKey(example);
        // 返回小于等于key的最大Key的key
        Person bkey = (Person) treeMap.floorKey(example);
        // 返回集合的副本
        TreeMap cloneMap = (TreeMap) treeMap.clone();
        cloneMap.put(p1,"p1-6666");
        // 返回集合的全部Key,并且是逆序的
        NavigableSet navigableSet = treeMap.navigableKeySet();
        // 把集合逆序返回
        NavigableMap maps = treeMap.descendingMap();
        // 返回集合中最小的值、最大的值
        Entry thLittle = treeMap.firstEntry();
        Entry thBig = treeMap.lastEntry();
        // 返回集合中最小的key、最大的key
        Person littleKey = (Person) treeMap.firstKey();
        Person bigKey = (Person) treeMap.lastKey();
        // 返回Key小于参数的所有元素
        SortedMap map = treeMap.headMap(example);
        // 当inclusive为true时,就是返回Key小于等于toKey的所有元素
        NavigableMap mapTrue = treeMap.headMap(example,true);
        //返回Key大于key的所有元素、key
        Entry entry = treeMap.higherEntry(example);
        Person person = (Person) treeMap.higherKey(example);
        // 截取集合中Key从fromKey到toKey的元素,否是截取他们本身,取决于true或者false
        NavigableMap subs = treeMap.subMap(example,false,p4,false);
        // 截取集合中Key从fromKey到toKey的元素,包括fromKey,不包括toKey
        SortedMap sortedMap = treeMap.subMap(p1,p4);
        // 截取Key大于等于fromKey的所有元素
        SortedMap mp = treeMap.tailMap(p1);
        // 当inclusive为true时,截取Key大于等于fromKey的所有元素,否则截取Key大于fromKey的所有元素
        SortedMap s1 = treeMap.tailMap(p1,false);
        // 删除key最小的元素、最大元素
        Entry delLest = treeMap.pollFirstEntry();
        Entry delLast = treeMap.pollLastEntry();

    }
}

key因为是自定义变量的,所以上边用example或者p1,p2等来代替了
结果就自己打印出来看看吧

HashMap 和 TreeMap的区别
  • 排序

    • HashMap不保证元素的顺序,迭代顺序也是不确定的
    • TreeMap 基于红黑树的实现,会根据键的自然排序或自定义的比较器对键进行排序。TreeMap保证了元素的顺序,可以按照键的升序进行遍历。
  • 时间复杂度:

    • HashMap的查找、插入和删除操作的平均时间复杂度为O(1)
    • TreeMap的查找、插入和删除操作的时间复杂度为O(log n),其中n为元素的数量
  • 性能

    • HashMap提供了常数时间的性能(基于哈希表)
    • TreeMap提供了对数时间的性能(基于红黑树)
  • 25
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值