Java进阶13讲__第八讲

集合:Collection,List,Set,Map

集合体系

集合结构

单列集合

1.Collection

1.初识Collection

package cn.hdc.oop8.Collection;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * 目标:认识collection集合体系
 */

public class Test1 {
    public static void main(String[] args) {
        //简单确认一下collection集合的特点
        ArrayList<String> list = new ArrayList<>();
        list.add("java1");
        list.add("java2");
        list.add("java1");
        list.add("java2");
        System.out.println(list);
        //[java1, java2, java1, java2]//有序,可重复,有索引
        HashSet<String> set = new HashSet<>();
        set.add("java1");
        set.add("java2");
        set.add("java1");
        set.add("java2");
        set.add("java3");
        System.out.println(set);
        //[java3, java2, java1]//无序,不可重复,无索引
        
    }
}

2.常用API

package cn.hdc.oop8.Collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class api {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();//实现类对象给到顶级的父类接口,这是一种多态现象
        //1.public boolean add (E e):添加元素,添加成功返回true。
        System.out.println(list.add("jsz"));
        //2.public void clear(): 清空集合的元素
        list.clear();
        System.out.println(list);
        //3.public boolean isEmpty():判断集合是否为空 是空返回true,反之。
        System.out.println(list.isEmpty());
        //4.public int size():获取集合的大小。
        System.out.println(list.size());
        //5.public boolean contains(object obj): 判断集合中是否包含某个元素。
        System.out.println(list.contains("jsz"));
        //6.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
        System.out.println(list.remove("jsz"));
        //7.public 0bject[] toArray():把集合转换成数组
        System.out.println(Arrays.toString(list.toArray()));
        Object[] objects = list.toArray();//默认是Object类型的数组
        //转成指定类型的数组
        String[] strArr = list.toArray(new String[list.size()]);
        System.out.println(Arrays.toString(strArr));
        System.out.println("-----------------------------------------------------");
        //把一个集合中的数据倒入到另一个集合中去
        Collection<String> lis = new ArrayList<>();
        lis.add("java1");
        lis.add("java2");
        Collection<String> lis1 = new ArrayList<>();
        lis1.add("java3");
        lis1.addAll(lis);//addAll:把lis集合的全部数据倒入到lis1集合中,lis1和lis集合的数据类型需一致
        System.out.println(lis1);
    }
}

3.遍历方式

1.迭代器

package cn.hdc.oop8.Collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class iterator {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("庆桑");
        list.add("乐桑");
        list.add("卓桑");
        list.add("毅桑");
        System.out.println(list);
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {//hasNext判断当前位置有没有数据,位置的变化是由next进行的,hasNext与下一个位置有没有数据无关,不要被名称表面所迷惑
            System.out.println(iterator.next());//hasNext判断一次,取一次
            /**
             * 错误写法:
             * while (iterator.hasNext()) {
             *     System.out.println(iterator.next());
             *     System.out.println(iterator.next());
             * }
             * 这样的话当集合里面数据为奇数个时第二个next会报空
             */
        }
    }
}

2.增强for循环

package cn.hdc.oop8.Collection;

import java.util.ArrayList;
import java.util.Collection;

public class forPlus {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("庆桑");
        list.add("乐桑");
        list.add("卓桑");
        list.add("毅桑");
        System.out.println(list);
        for (String str : list) {
            System.out.println(str);
        }
    }
}

 增强for除了可以用来遍历集合,还可以用来遍历数组

3.Lambda

package cn.hdc.oop8.Collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;

public class Lambda {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("庆桑");
        list.add("乐桑");
        list.add("卓桑");
        list.add("毅桑");
        System.out.println(list);
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        System.out.println("-----------------------------------------");
        list.forEach((String s) -> {
                    System.out.println(s);
                }
        );
        System.out.println("-----------------------------------------");
        list.forEach(item -> System.out.println(item));
        System.out.println("-----------------------------------------");
        list.forEach(System.out::println);
    }
}

为什么没有支持for循环?

因为for循环必须是支持索引的,Collection集合并不是所有集合都支持索引

4.案例

package cn.hdc.oop8.Collection.demo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

public class Test1 {
    public static void main(String[] args) {
        Collection<Movies> list = new ArrayList<>();
        list.add(new Movies("《肖申克的救赎》", 9.7, "罗宾斯"));
        list.add(new Movies("《霸王别姬》", 9.6, "张国荣、张丰毅"));
        list.add(new Movies("《阿甘正传》", 9.5, "汤姆.汉克斯"));
        for (Movies movies : list) {
            System.out.println(movies);
        }
        Iterator<Movies> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        list.forEach(System.out::println);
    }
}

package cn.hdc.oop8.Collection.demo;

public class Movies {
    private String name;
    private double score;
    private String actor;

    @Override
    public String toString() {
        return "Movies{" +
                "name='" + name + '\'' +
                ", score=" + score +
                ", actor='" + actor + '\'' +
                '}';
    }

    public Movies() {
    }

    public Movies(String name, double score, String actor) {
        this.name = name;
        this.score = score;
        this.actor = actor;
    }

    public String getName() {
        return name;
    }

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

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }
}

2.List

1.特点、特有方法

package cn.hdc.oop8.List;

import java.util.ArrayList;
import java.util.List;

public class special {
    public static void main(String[] args) {
        //1.创建一个ArrayList集合对象(有序、可重复、有索引)
        List<String> list = new ArrayList<>();//多态
        list.add("666");
        list.add("777");
        list.add("888");
        list.add("999");
        System.out.println(list);
        System.out.println("--------------------------------------");
        //2.public void add(int index,E element):在某个索引位置插入元素。
        list.add(0, "java");
        list.add(4, "java");
        list.add(6, "java");
        System.out.println(list);
        System.out.println("--------------------------------------");
        //3.public E remove(int index): 根据索引删除元素,返回被删除元素
        System.out.println("删除的元素是:" + list.remove(0));
        System.out.println(list);
        System.out.println("--------------------------------------");
        //4.public E get(int index): 返回集合中指定位置的元素。
        System.out.println("集合首位元素是:" + list.get(0));
        System.out.println("--------------------------------------");
        //5.public E set(int index,E element): 修改索引位置处的元素,修改成功后,会返回原来的数据
        list.set(5, "这是末尾元素");
        System.out.println(list);
        System.out.println("--------------------------------------");
    }
}

2.遍历方式

3.ArrayList集合的底层原理

4.LinkedList集合的底层原理

1.什么是链表

 2.链表的特点

3.单链表和双链表

4.LinkedList集合的底层原理

5.应用场景

 1.用于设计队列

package cn.hdc.oop8.List;

import java.util.LinkedList;

public class LinkedListTest {
    public static void main(String[] args) {
//        创建一个队列
        LinkedList<String> list = new LinkedList<>();
        //入队
        list.addLast("sq");
        list.addLast("sq1");
        list.addLast("sq2");
        list.addLast("sq3");
        list.addLast("sq4");
        list.addLast("sq5");
        list.addLast("sq6");
        list.addLast("sq7");
        System.out.println(list);
        //出队
        list.removeFirst();
        list.removeFirst();
        list.removeFirst();
        System.out.println(list);
    }
}

2.用于设计栈 

//          创建一个栈
        LinkedList<String> list1 = new LinkedList<>();
        //压栈push
        list1.addFirst("wsn");
        list1.addFirst("wzn");
        list1.addFirst("wyr");
        System.out.println(list1);
        //弹栈pop
        list1.removeFirst();
        list1.removeFirst();
        System.out.println(list1);
        System.out.println("--------------------------------");
        list1.push("wsn");
        list1.push("wzn");
        list1.push("wyr");
        System.out.println(list1);
        list1.pop();
        list1.pop();
        list1.pop();
        System.out.println(list1);
        System.out.println("--------------------------------");

3.Set

1.Set集合特点

package cn.hdc.oop8.Set;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

public class SetTest1 {
    public static void main(String[] args) {
        Set<Integer> s1 = new TreeSet<>();//可排序不重复无索引
        s1.add(34);
        s1.add(36);
        s1.add(37);
        s1.add(37);
        s1.add(31);
        s1.add(33);
        s1.add(33);
        s1.add(34);
        System.out.println(s1);
        System.out.println("-------------------------------------------");
        Set<Integer> s = new LinkedHashSet<>();//有序不重复无索引
        s.add(4);
        s.add(6);
        s.add(7);
        s.add(7);
        s.add(1);
        s.add(3);
        s.add(3);
        s.add(4);
        System.out.println(s);
        System.out.println("-------------------------------------------");
        Set<Integer> set = new HashSet<>();//创建了一个HashSet的集合对象,一行经典代码,HashSet:无序不重复无索引
        set.add(666);
        set.add(555);
        set.add(555);
        set.add(777);
        set.add(777);
        set.add(888);
        System.out.println(set);

    }
}

 Set无特殊新增常用方法

 2.HashSet集合的底层原理

1.为什么添加的元素无序、不重复、无索引?

2.增删改查数据有什么特点,适合什么场景?

1.哈希值

2.底层原理

JDK8_Before

当集合数组长度有 默认数组长度 * 默认加载因子 即16*0.75=12时,也就是当HashSet存储了12个位置的元素时,集合会扩容成其的两倍。 

如果数组快占满了,会出现什么问题?该怎么办?

会出现:链表会过长,导致查询性能降低 的问题

应该:    扩容

JKD8_After 
 二叉查找树

平衡二叉树
红黑树

 3.HashSet集合去重

深入理解HashSet集合去重复的机制

package cn.hdc.oop8.Set.DuplicateRemove;

import cn.hdc.oop8.Set.Student;

import java.util.HashSet;

public class Test1 {
    public static void main(String[] args) {
        HashSet<Student> set = new HashSet<>();
        Student s1 = new Student("蜘蛛精", 25, 169.5);
        Student s2 = new Student("蜘蛛精1", 25, 169.5);
        Student s3 = new Student("蜘蛛精", 25, 169.5);
        Student s4 = new Student("蜘蛛精2", 25, 169.5);
        set.add(s1);
        set.add(s2);
        set.add(s3);
        set.add(s4);
        System.out.println(set);
        
    }
}

 重写HashSet的equals和hashCode方法

    //只要两个对象内容一样,就返回true
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
    }

    //只要两个对象内容一样,返回的哈希值就是一样的。
    @Override
    public int hashCode() {
        //姓名,年龄,身高
        return Objects.hash(name, age, height);
    }

重写一路回车,无需更改。

运行结果 

重写前

重写后

3.LinkedHashSet

4.TreeSet

1.定义

2.自定义排序规则

方式一

实现Comparable接口 

package cn.hdc.oop8.Set;

import java.util.Objects;

//public class Student {

public class Student implements Comparable<Student> {
    private String name;
    private int age;
    private double height;
    //TreeSet自定义排序规则
    //只要两个对象内容一样,就返回true
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
    }

    //只要两个对象内容一样,返回的哈希值就是一样的。
    @Override
    public int hashCode() {
        //姓名,年龄,身高
        return Objects.hash(name, age, height);
    }

......getter   setter  toString    有参   无参等.......

    //年龄降序
//    @Override
//    public int compareTo(Student o) {
//        return o.getAge() - this.getAge();
//    }
    //身高升序
    @Override
    public int compareTo(Student o) {
//        return this.getHeight() - o.getHeight() > 0 ? 1 : -1;
        return Double.compare(o.getHeight(), this.getHeight());
    }
}

compareTo需要的返回值是int
double数据类型的数据可以通过两种方式进行比较:

1.三元运算符
2.Double的compare方法

package cn.hdc.oop8.Set;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetTest2 {
    public static void main(String[] args) {
        //就近选择自己自带的比较器对对象进行排序
//        Set<Student> set = new TreeSet<>(Comparator.comparingInt(Student::getAge));
        Set<Student> set = new TreeSet<>();
        set.add(new Student("蜘蛛精", 250, 169.5));
        set.add(new Student("蜘蛛精1", 259, 169.6));
        set.add(new Student("蜘蛛精2", 257, 169.7));
        set.add(new Student("蜘蛛精3", 257, 169.8));
        System.out.println(set);

    }
}
方式二
package cn.hdc.oop8.Set;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetTest2 {
    public static void main(String[] args) {
        //就近选择自己自带的比较器对对象进行排序
        Set<Student> set = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        });
//        Set<Student> set = new TreeSet<>();
        set.add(new Student("蜘蛛精", 250, 169.5));
        set.add(new Student("蜘蛛精1", 259, 169.6));
        set.add(new Student("蜘蛛精2", 257, 169.7));
        set.add(new Student("蜘蛛精3", 257, 169.8));
        System.out.println(set);

    }
}

Comparable接口和TreeSet集合自带比较器Comparator同时存在时,就近使用集合自带的比较器对对象进行比较排序。

5.小结

1.Collection单列集合小结

2.补充

1.集合的并发修改异常问题

package cn.hdc.oop8.zongjie;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CollectionHighTogetherException {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("王麻子");
        list.add("许李国");
        list.add("李慕婉");
        list.add("藤化元");
        list.add("唐舞桐");
        list.add("圣采儿");
        System.out.println(list);
        //[王麻子, 李慕婉, 藤化元, 许立国, 唐舞桐, 圣采儿]
        //需求:需要找出集合中全部带“李”的名字并从集合中删除
//        Iterator<String> it = list.iterator();
//        while (it.hasNext()) {
//            if (it.next().contains("李")) {
//                list.remove(it.next());//控制台报错
//            }
//        }
        System.out.println("-----------------------------------------");
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            if (it.next().contains("李")) {
                it.remove();//迭代器自带删除方法
            }
        }
        System.out.println("-----------------------------------------");
        //使用for循环遍历集合并删除集合中带“李”的名字
//        for (int i = 0; i < list.size(); i++) {
//            if (list.get(i).contains("李")) {
//                list.remove(i);//删除可能不完全
//            }
//        }
        System.out.println("-----------------------------------------");
//        for (int i = list.size() - 1; i >= 0; i--) {
//            if (list.get(i).contains("李")) {
//                list.remove(i);//可以删除
//            }
//        }
        System.out.println("-----------------------------------------");
        //增强for循环和Lambda表达式是无法解决这个问题的,他们都是迭代器的一种简化写法,但又无法调用迭代器的删除方法
//        for (String s : list) {
//            if (s.contains("李")) {
//                list.remove(s);
//            }
//        }
        System.out.println(list);
    }
}
2.可变参数

定义

可变参数注意事项

1.一个形参列表中,只能有一个可变参数
错误案例:public static void t(int... id,int...num) {}

2.可变参数必须放在形参列表的最后面
错误案例:public static void t(int... id,int age) {}

3.可变参数在方法内部就是一个数组,并且是一个有序数组

3.Collections工具类

1.定义及常用方法

package cn.hdc.oop8.collections;

import java.util.*;

public class collections {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();

        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        System.out.println(list);
//1、public static <T> boolean addAll(collection<? super T>c,T...elements):为集合批量添加数据
        Collections.addAll(list, 6, 7, 8, 9, 0);
        System.out.println(list);
//2、public static void shuffle(List<?> list):打乱List集合中的元素顺序。
        Collections.shuffle(list);
        System.out.println(list);
//3、 public static <T> void sort(List<T> list):对List集合中的元素进行升序排序。
        Collections.sort(list);
        System.out.println(list);
//4、public static <T> void sort(List<T> list,Comparator<? super T> c):对List集合中元素,按照比较器对象指定的规则进行排序。
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        System.out.println(list);
    }
}

 自定义对象排序规则

        List<Student> set = new ArrayList<>();
        set.add(new Student("蜘蛛精", 250, 169.5));
        set.add(new Student("蜘蛛精1", 259, 169.6));
        set.add(new Student("蜘蛛精2", 257, 169.7));
        set.add(new Student("蜘蛛精3", 257, 169.8));
//        System.out.println(set);
        Collections.sort(set, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        System.out.println(set);

4.Collection案例:斗地主

1.分析业务需求

2.分析实现

双列集合

1.Map

1.认识Map集合

2.应用场景

 3.Map集合体系

特点

package cn.hdc.oop8.Map;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

public class knowMap {
    public static void main(String[] args) {
        Map<String, Integer> map = new LinkedHashMap<>();//多态、经典代码,按照键无序、不重复、无索引
//        Map<String, Integer> map = new HashMap<>();//多态、经典代码,按照键无序、不重复、无索引
        map.put("dsb", 100);
        map.put("dsb", 220);//后添加的数据会覆盖之前添加的数据
        map.put("sj", 2);
        map.put("java", 2);
        map.put(null, null);
        System.out.println(map);
        Map<Integer, String> map1 = new TreeMap<>();
        map1.put(23, "java");
        map1.put(23, "MySQL");//后覆前
        map1.put(19, "Vue");
        map1.put(20, "Ele");
        System.out.println(map1);

    }
}

4.Map集合常用方法

package cn.hdc.oop8.Map;

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

public class MapAPI {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<>();
        map.put(23, "Java");
        map.put(24, "MySQL");//后覆前
        map.put(19, "Vue");
        map.put(20, "Ele");
        map.put(27, "Ajax");
        map.put(29, "React");
        HashMap<Integer, String> mp = (HashMap<Integer, String>) ((HashMap<Integer, String>) map).clone();
        //2.public int size():获取集合的大小
        System.out.println(map.size());
        System.out.println(mp.size());
        System.out.println("3=========");
        //3、public void clear():清空集合
        map.clear();
        System.out.println(map);
        System.out.println(mp);
        System.out.println("4=========");
        // 4.public boolean isEmpty():判断集合是否为空,为空返回true,反之!
        System.out.println(map.isEmpty());
        System.out.println(mp.isEmpty());
        System.out.println("5=========");
        //5.public V get(object key):根据键获取对应值
        System.out.println(mp.get(20));
        System.out.println(mp.get(201));
        System.out.println("6=========");
        //6.public V remove(object key):根据键删除整个元素(删除键会返回键的值):
        System.out.println(mp.remove(20));
        System.out.println(mp.remove(201));
        System.out.println("7=========");
        //7.public boolean containsKey(0bject key):判断是否包含某个键 ,包含返回true,反之
        System.out.println(mp.containsKey(29));
        System.out.println(mp.containsKey(292));
        System.out.println("8=========");
        //8.public boolean containsValue(object value): 判断是否包含某个值。
        System.out.println(mp.containsValue("Java"));
        System.out.println(mp.containsValue("JavaSpring"));
        System.out.println("9=========");
        //9.public Set<K> keySet():获取Map集合的全部键。
        System.out.println(map.keySet());
        System.out.println(mp.keySet());
        System.out.println("10=========");
        //10.public Collection<V> values():获取Map集合的全部值。
        System.out.println(map.values());
        System.out.println(mp.values());
        System.out.println("11=========");
        //11.把其他Map集合的数据倒入自己的集合中
        map.putAll(mp);
        map.putAll(mp);
        System.out.println(map);
        System.out.println(map.values());
    }
}

5.Map集合的遍历方式

 Map遍历测试模版

package cn.hdc.oop8.Map.bianli;

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

public class m1 {
    public static void main(String[] args) {
        // 创建一个 HashMap 并填充数据
        Map<Integer, String> map = generateFixedMap();

        // 打印 HashMap
        System.out.println(map);
    }
    public static Map<Integer, String> generateFixedMap() {
        Map<Integer, String> map = new HashMap<>();

        // 填充固定的数据
        map.put(1, "Java");
        map.put(2, "Python");
        map.put(3, "C++");
        map.put(4, "JavaScript");
        map.put(5, "Go");
        map.put(6, "Ruby");
        map.put(7, "Swift");
        map.put(8, "Kotlin");
        map.put(9, "Rust");
        map.put(10, "PHP");
        map.put(11, "Scala");
        map.put(12, "TypeScript");
        map.put(13, "Dart");
        map.put(14, "Perl");
        map.put(15, "Lua");
        map.put(16, "Haskell");
        map.put(17, "Groovy");
        map.put(18, "Julia");
        map.put(19, "Elixir");
        map.put(20, "R");

        return map;
    }
}

1.方式一:键找值

        Set<Integer> set = map.keySet();
        for (Integer integer : set) {
            System.out.println(integer + ":" + map.get(integer));
        }

2.方式二:键值对

        Set<Map.Entry<Integer, String>> set = map.entrySet();
        for (Map.Entry<Integer, String> entry : set) {
            System.out.println(entry);
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }

3.方式三:Lambda

        map.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer integer, String s) {
                System.out.println(integer + ":" + s);
            }
        });
        map.forEach((Integer integer, String s) -> {
            System.out.println(integer + ":" + s);
        });
        map.forEach((integer, s) -> System.out.println(integer + ":" + s));

6.Map集合案例:统计投票人数

案例代码 

package cn.hdc.oop8.Map.demo;

import java.util.*;

public class d1 {
    public static void main(String[] args) {
        List<String> list = createList();
        long t1 = System.currentTimeMillis();
        Map<String, Integer> map = statistics(list);
        System.out.println(map);
        long t2 = System.currentTimeMillis();
        System.out.println("time1:" + (t2 - t1));
        long t3 = System.currentTimeMillis();
        int a = 0, b = 0, c = 0, d = 0;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).equals("A")) {
                a++;
            } else if (list.get(i).equals("B")) {
                b++;
            } else if (list.get(i).equals("C")) {
                c++;
            } else {
                d++;
            }
        }
        System.out.println("A:" + a + "\tB:" + b + "\tC:" + c + "\tD:" + d);
        long t4 = System.currentTimeMillis();
        System.out.println("time2:" + (t4 - t3));
    }

    private static Map<String, Integer> statistics(List<String> list) {
        Map<String, Integer> map = new HashMap<>();
        for (String s : list) {
            if (map.containsKey(s)) {
                map.put(s, map.get(s) + 1);
            } else {
                map.put(s, 1);
            }
        }
//        for (int i = 0; i < list.size(); i++) {
//            if (map.containsKey(list.get(i))) {
//                Integer v = map.get(list.get(i));
//                map.put(list.get(i), ++v);
//            } else {
//                map.put(list.get(i), 1);
//            }
//        }
        return map;
    }

    private static List<String> createList() {
        String[] strArr = {"A", "B", "C", "D"};
        List<String> list = new ArrayList<>();
        Random r = new Random();
        for (int i = 0; i < 80; i++) {
            list.add(strArr[r.nextInt(4)]);
        }
        return list;
    }
}

运行结果 

通过比较可得,map相较for循环来说,更快。

2.HashMap

1.底层原理

2.底层是基于哈希表实现的

 3.案例代码

package cn.hdc.oop8.Map.HashMap;

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

public class t1 {
    public static void main(String[] args) {
        Map<Student, String> map = new HashMap<>();
        map.put(new Student("wzn", 158.4, 20), "泗上");
        map.put(new Student("wzn", 158.4, 20), "辛集");
        map.put(new Student("wsn", 162.7, 21), "晋州");
        map.put(new Student("wyr", 165.2, 22), "邯郸");
        map.put(new Student("jsz", 178.7, 22), "北京");
        System.out.println(map);
    }
}

重写hashCode和equals方法 

package cn.hdc.oop8.Map.HashMap;

import java.util.Objects;

public class Student {
    private String name;
    private double height;
    private int age;

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

    @Override
    public int hashCode() {
        return Objects.hash(name, height, age);
    }
    ......有参、无参、getter、setter、toString
}

3.LinkedHashMap集合原理

1.原理

2.使用 

4.TreeMap集合的原理、使用

1.原理 

2.使用

package cn.hdc.oop8.Map.TreeMap;

import cn.hdc.oop8.Map.HashMap.Student;

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

public class t2 {
    public static void main(String[] args) {
        // 使用情况一的Comparator
        Comparator<Student> comparator1 = new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() > o2.getAge() ? 1 : -1;
            }
        };
        Map<Student, String> map1 = new TreeMap<>(comparator1);
        map1.put(new Student("wyr", 165.2, 22), "邯郸");
        map1.put(new Student("jsz", 178.7, 22), "北京");
        System.out.println("Map with Comparator 1:\n " + map1);

        // 使用情况二的Comparator
        Comparator<Student> comparator2 = (o1, o2) -> {
            int ageCompare = Integer.compare(o1.getAge(), o2.getAge());
            int heightCompare = Double.compare(o1.getHeight(), o2.getHeight());
            if (ageCompare != 0) {
                return ageCompare;
            } else if (heightCompare != 0) {
                return heightCompare;
            } else {
                return o1.getName().compareTo(o2.getName());
            }
        };
        Map<Student, String> map2 = new TreeMap<>(comparator2);
        map2.put(new Student("wyr", 165.2, 22), "邯郸");
        map2.put(new Student("jsz", 178.7, 22), "北京");
        System.out.println("Map with Comparator 2: \n" + map2);
    }
}

2.1运行结果

3.可能会遇到的问题参考:

自定义对象排序方法之谁前谁后问题-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/XiaomeiGuiSnJs/article/details/141780415?spm=1001.2014.3001.5501

5.补充知识:集合的嵌套

1.什么是集合的嵌套

即一个集合内的元素是另一个集合

2.案例:省和市

 3.案例代码

package cn.hdc.oop8.Map.qiantao;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class t1 {
    public static void main(String[] args) {
        Map<String, ArrayList<String>> map = new HashMap<>();
        ArrayList<String> l1 = new ArrayList<>();
        Collections.addAll(l1, "南京市", "扬州市", "苏州市", "无锡市", "常州市");
        ArrayList<String> l2 = new ArrayList<>();
        Collections.addAll(l2, "武汉市", "孝感市", "十堰市", "宜昌市", "鄂州市");
        ArrayList<String> l3 = new ArrayList<>();
        Collections.addAll(l3, "石家庄市", "唐山市", "邢台市", "保定市", "张家口市");
        map.put("江苏省", l1);
        map.put("湖北省", l2);
        map.put("河北省", l3);
        System.out.println(map);
        System.out.println(map.get("河北省"));
        for (String s : map.get("江苏省")) {
            System.out.println(s);
        }
        map.forEach((p, c) -> System.out.println(p + ":" + c));
    }
}

4.运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值