0
点赞
收藏
分享

微信扫一扫

Map集合,hashMap的存储过程,Set集合

waaagh 2022-01-23 阅读 65

1. Map接口

Map接口的特点

  1. map集合的结构是:键值对、KEY与VALUE、Map.Entry<K,V>的映射关系

  2. map中key值不允许重复,如果重复,对应的value会被覆盖

  3. map中的映射关系是无序的

  4. map没有自己的迭代器,所以迭代时通常需要转成set集合来迭代

Map集合方法总结

简单方法:

map单个集合间的操作

map的迭代

package cn.tedu.map;

import java.util.*;

/*本类用于测试map接口*/
public class MapDemo {
    public static void main(String[] args) {
        //1.创建map对象
        /*Map中的数据要符合映射规则,需要同时制定k与v的数据类型
         * 至于k和v具体制定成什么类型,取决于业务的具体要求*/
        Map<Integer, String> map = new HashMap();
        //2.向Map集合存入数据,取决于业务的具体要求
        map.put(9527, "白骨精");
        map.put(9528, "黑熊精");
        map.put(9529, "鲤鱼精");
        map.put(9530, "黄毛怪");
        map.put(9531, "黑熊精");
        map.put(9527, "女儿国国王");
        System.out.println(map);//{9527=白骨精, 9528=黑熊精, 9529=鲤鱼精, 9530=黄毛怪}
        /*1.map中存放着的都是无序的数据
         * 2.map中的value中的value可以重复
         * 3.map中的key不允许重复,如果重复,新value会把旧value覆盖
         * 比如女儿国国王和白骨精的key都是9527,白骨精被覆盖掉*/

        //3.进行方法测试
//        map.clear();//清空集合
//        System.out.println(map);//{}
        System.out.println(map.equals("黄毛怪"));//false,判断"黄毛怪"是否与集合对象相等
        System.out.println(map.isEmpty());//判断是否为空false
        System.out.println(map.size());//5,获取map集合中键值对的个数
        System.out.println(map.containsKey(9527));//true,判断map集合是否包含指定的key-键
        System.out.println(map.containsValue("白骨精"));//false,判断map集合是否包含value-值

        //将map集合中的所有value值取出,放入Collection集合中,
        //Collection<Type>中Type的类型,取决于map中value的类型
        Collection<String> values = map.values();
        System.out.println(values);//[女儿国国王, 黑熊精, 鲤鱼精, 黄毛怪, 黑熊精]

        //4.map集合的迭代方式1
        /*我们降妖谱遍历map中的数据,但是map集合本身没有自己的迭代器,
        * 所以需要先将map集合转为Set集合以后,再使用set的迭代器进行迭代
        * 代码:Set<Key>=Map.keySet();
        * 作用:将map中所有的key值取出,存入set集合中,此处set的泛型是Integer
       */
        Set<Integer> set = map.keySet();//将map集合转为set集合,set中存的是map的key
        System.out.println(set);//[9527, 9528, 9529, 9530, 9531]
        Iterator<Integer> it = set.iterator();
        while(it.hasNext()){
//        System.out.print(it.next()+" ");//9527 9528 9529 9530 9531
            Integer key = it.next();
            String value = map.get(key);
            System.out.print("("+key+"="+value+")");//(9527=女儿国国王)(9528=黑熊精)(9529=鲤鱼精)(9530=黄毛怪)(9531=黑熊精)
        }
        //5.map的迭代方式二
        /*遍历map集合,需要先把map集合转换为set集合
        * 本方案是一对键值对看成是一个Entry
        * 代码:Map.Entry<key,value>=map.entrySet();
        * Map.Entry<k,v>,这里是Map.Entry<Integer,String>*/
        System.out.println("entrySet(--------------------)");
        System.out.println();
        Set<Map.Entry<Integer, String>> set2 = map.entrySet();
        Iterator<Map.Entry<Integer, String>> iterator = set2.iterator();
        while (iterator.hasNext()){
            Map.Entry<Integer, String> entry = iterator.next();
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.print("*"+key+"-"+value+"*");//*9527-女儿国国王**9528-黑熊精**9529-鲤鱼精**9530-黄毛怪**9531-黑熊精*
        }
    }
}

 

2.HashMap的存储过程:

  1. HashMap的结构是数组+链表 或者 数组+红黑树 的形式

  2. HashMap底层的Entry[ ]数组,初始容量为16,加载因子是0.75f,扩容按约为2倍扩容

  3. 当存放数据时,会根据hash(key)%n算法来计算数据的存放位置,n就是数组的长度,其实也就是集合的容量

  4. 当计算到的位置之前没有存过数据的时候,会直接存放数据

  5. 当计算的位置,有数据时,会发生hash冲突/hash碰撞 解决的办法就是采用链表的结构,在数组中指定位置处以后元素之后插入新的元素 也就是说数组中的元素都是最早加入的节点

  6. 如果链表的长度>8并且数组长度>64时,链表会转为红黑树,当链表的长度<6时,会重新恢复成链表

 

 

 

package cn.tedu.map;

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

/*练习*/
public class Demo {
    public static void main(String[] args) {
        //1.创建map对象
        /*Map中的数据要符合映射规则,需要同时制定k与v的数据类型
         * 至于k和v具体制定成什么类型,取决于业务的具体要求*/
        Map<Integer, String> map = new HashMap();
        //2.向Map集合存入数据,取决于业务的具体要求
        map.put(9527, "白骨精");
        map.put(9528, "黑熊精");
        map.put(9529, "鲤鱼精");
        map.put(9530, "黄毛怪");
        map.put(9531, "黑熊精");
        map.put(9527, "女儿国国王");
        System.out.println(map);//{9527=白骨精, 9528=黑熊精, 9529=鲤鱼精, 9530=黄毛怪}
        /*迭代方式一*/
        Set<Integer> set = map.keySet();
        Iterator<Integer> it = set.iterator();
        while (it.hasNext()) {
            Integer key = it.next();
            String values = map.get(key);
            System.out.println("*" + key + "=" + values);
        }
        /*迭代方式二*/
        Set<Map.Entry<Integer, String>> entries = map.entrySet();
        Iterator<Map.Entry<Integer, String>> entry = entries.iterator();
        while (entry.hasNext()) {
            Map.Entry<Integer, String> entrys = entry.next();
            System.out.println(entrys.getKey());
            System.out.println(entrys.getValue());
        }
    }
}

 

3. Set接口

Set接口的特点

set集合没有重复的元素 set集合的元素是无序的 set集合可以存null值,并且null最多有一个 我们自定义对象如果想去重,需要在自定义类中添加重写的equals()与hashCode()

集合学习的方法

学习父级的公共方法,学习子类的创建方式,学习各种集合的特点

关于List大多都是与下标有关的操作 关于Set通常都是去重的操作 关于map通常都是映射关系,也就是键值对 API要常练习,方法互相之间没有任何关系,用哪个,查哪个

package cn.tedu.collection;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;

/*本类用于测试Set*/
public class TestSet {
    public static void main(String[] args) {
        //1.创建集合对象
        HashSet<String> set = new HashSet<>();
        set.add("紫霞仙子");
        set.add("至尊宝");
        set.add("蜘蛛精");
        set.add("紫霞仙子");
        System.out.println(set);//[蜘蛛精, 至尊宝, 紫霞仙子]
        /*1.Set集合中的元素都是没有顺序
         * 2.Set集合中的元素不能重复,重复了也没有任何效果
         * Set集合可以存null值,只能存一个*/
        set.add(null);
        set.add(null);
        System.out.println(set);//[蜘蛛精, null, 至尊宝, 紫霞仙子]
        System.out.println(set.contains("唐僧"));//false,判断集合是否包含唐僧
        System.out.println(set.isEmpty());//false
        System.out.println(set.remove(null));//true
        System.out.println(set);//[蜘蛛精, 至尊宝, 紫霞仙子]
        System.out.println(set.size());//3
        System.out.println(Arrays.toString(set.toArray()));//[蜘蛛精, 至尊宝, 紫霞仙子]

        HashSet<String> set2 = new HashSet<>();
        set2.add("小脑服");
        set2.add("小兔纸");
        set2.add("小海藤");
        set2.add("发福蝶");
        System.out.println(set2);//[小兔纸, 发福蝶, 小脑服, 小海藤]

        set.addAll(set2);
        System.out.println(set);//[蜘蛛精, 小兔纸, 发福蝶, 小脑服, 至尊宝, 小海藤, 紫霞仙子]
        System.out.println(set.containsAll(set2));//true
        System.out.println(set.removeAll(set2));//true
        System.out.println(set.contains(set2));//false
//        set.retainAll(set2);
//        System.out.println(set);//[],没有公共元素

        /*Set迭代*/
        Iterator<String> it = set2.iterator();
        while(it.hasNext()){
            System.out.print(it.next()+" ");//小兔纸 发福蝶 小脑服 小海藤
        }

    }
}

 

package cn.tedu.pojo;

import java.util.Objects;

public class Student {
    private  String name;
    private  Integer age;
    private  char sex;

    public Student(String name, Integer age, char sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    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 char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

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

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

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



package cn.tedu.collection;
import cn.tedu.pojo.Student;
import java.util.HashSet;
/*本类用于测试自定义类对象的去重*/
public class TestSet2 {
    public static void main(String[] args) {
        HashSet<Student> set = new HashSet<>();
        Student s1 = new Student("秦晓燕",18,'女');
        Student s2 = new Student("xxx", 30, '男');
        Student s22 = new Student("xxx", 30, '男');
        /*如果set中存放的是我们自定义的类型
         * 需要给自定义类中添加重写的equals()与hashCode(),才会去重
         * 不然会认为s2和s22的地址值不同,是两个不同的对象,不会去重*/
        set.add(s1);
        set.add(s2);
        set.add(s22);
        System.out.println(set);
    }
}

 

举报

相关推荐

0 条评论