第九周笔记

1. Set集合

1.1 Set集合存储元素不重复的原理

Set集合在调用add方法的时候,add方法会调用元素的hashCode方法和equals方法,判断元素是否重复。

public class DemoHashSetSaveString {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        String s1 = new String("abc");
        String s2 = new String("abc");
        
		//add方法会调用s1的hashCode方法,计算字符串“abc”的哈希值
		//然后在集合中找有没有哈希值和这个哈希值一样的元素,发现没有,就把s1存储到集合中
        set.add(s1);
        //add方法会调用s2的hashCode方法,计算字符串“abc”的哈希值
        //然后在集合中找有没有哈希值和这个哈希值相同的元素,发现有(哈希冲突)
        //s2会调用equals方法和哈希值相同的元素进行比较,即s2.equals(s1),返回true,即两元素哈希值相同,且equals方法返回true,就认定两元素相同,就不会把s2存储到集合中
        set.add(s2);
        //add方法会调用“123”的hashCode方法,计算字符串“123”的哈希值
		//然后在集合中找有没有哈希值和这个哈希值一样的元素,发现没有,就把“123”存储到集合中
        set.add("123");
        //同s2
        set.add("abc");

        System.out.println(set); //[123, abc] 
    }
}

1.2 HashSet存储自定义类型的元素

set集合保证元素唯一:存储的元素,必须重写hashCode方法和equals方法

import java.util.Objects;

public class Person {
    private int age;
    private String name;

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

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

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

    public Person() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }
}

若要保证存储的元素不重复,自己定义的类中需要重写hashCode方法和equals方法。

import java.util.HashSet;

public class DemoHashSetSavePerson {
    public static void main(String[] args) {
        HashSet<Person> set = new HashSet<>();
        Person p1 = new Person(9,"猪猪侠");
        Person p2 = new Person(9,"猪猪侠");
        Person p3 = new Person(10,"猪猪侠");

        //要求:同名同年龄的人只存储一次
        set.add(p1);
        set.add(p2);
        set.add(p3);

        System.out.println(set);  //[Person{age=9, name='猪猪侠'}, Person{age=10, name='猪猪侠'}]
    }
}

1.3 LinkedHashSet集合

java.util.LinkedHashSet集合 extends HashSet集合

LinkedHashSet集合特点: 底层是一个哈希表(数组+链表/红黑树)+链表,多了一条链表用来记录元素的存储顺序,保证元素有序。

import java.util.HashSet;
import java.util.LinkedHashSet;

public class DemoLinkedHashSet {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("www");
        set.add("abc");
        set.add("abc");
        set.add("ppp");

        System.out.println(set); //[ppp, abc, www],无序不允许重复

        LinkedHashSet<String> linked = new LinkedHashSet<>();
        linked.add("www");
        linked.add("abc");
        linked.add("abc");
        linked.add("ppp");

        System.out.println(linked);  //[www, abc, ppp],有序不允许重复
    }
}

1.4 可变参数

可变参数是JDK1.5之后出现的新特性。

使用前提: 当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数。

使用格式: 定义方法的时候使用
修饰符 返回值类型 方法名(数据类型…参数名){}

可变参数的原理: 可变参数底层就是一个数组,根据传递参数的个数不同,会创建不同长度的数组,来存储这些参数。

public class DemoVarArgs {
    public static void main(String[] args) {
        int p= add(1, 2, 3);
        System.out.println(p);
    }
    //定义计算0-n个整数的和的方法
    //add()创建一个长度为0的数组,add(1,2,3)创建一个长度为3的数组存储传递过来的参数
    public static int add(int...arr){
        int sum = 0;
        for(int i : arr){
            sum += i;
        }
        return sum;
    }
}

可变参数的注意事项:

  1. 一个方法的参数列表,只能有一个可变参数。
  2. 如果方法的可变参数有多个,那么可变参数必须写在参数列表的末尾。

2.Collections集合

java.utils.Collections是集合工具类,用来对集合进行操作。

2.1 addAll&shuffle方法

  • public static boolean addAll(Collection c, T… elements):往集合中添加一些元素;
  • public static void shuffle(List<?> list):打乱集合顺序。

2.2 sort(List)方法

public static void sort(List list):将集合中的元素按照默认规则排序(默认为升序)。

sort(List list)使用前提: 被排序的集合里存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序的规则。

Comparable接口的排序规则: 自己(this) - 参数 (升序),参数 - 自己(this) (降序)。

import java.util.Objects;

public class Person implements Comparable<Person>{
    private int age;
    private String name;

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

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

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

    public Person() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }


    @Override
    public int compareTo(Person o) {
        //按年龄升序排序
        return this.getAge() - o.getAge();
        //return o.getAge() - this.getAge();  //降序排序
    }
}

2.3 sort(List, Comparator)方法

public static void sort(List list, Comparator<? super T>):将集合中的元素按照指定规则排序。

Comparator和Comparable的区别:
Comparator:相当于找一个第三方的裁判,比较两个
Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,重写比较的规则compareTo方法

Comparator的排序规则: o1 - o2升序,o2 - o1降序

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

public class DemoCollections {
    public static void main(String[] args) {
    //    demo1();
     //   demo2();
        demo3();
    }

    public static void demo1() {
        ArrayList<String> list = new ArrayList<>();
        //添加多个元素
        Collections.addAll(list,"a","b","c","d","e");
        System.out.println(list); //[a, b, c, d, e]
        //打乱顺序,每次都不一样
        Collections.shuffle(list);
        System.out.println(list); //[c, e, b, a, d]
    }

    public static void demo2() {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"a","d","e","c","b");
        System.out.println(list);  //[a, d, e, c, b]
        //按升序来排序
        Collections.sort(list);
        System.out.println(list);  //[a, b, c, d, e]
        //自定义类型的排序
        ArrayList<Person> list2 = new ArrayList<>();
        list2.add(new Person(10, "张三"));
        list2.add(new Person(8, "李四"));
        list2.add(new Person(12, "王五"));
        Collections.sort(list2);
        System.out.println(list2);  //[Person{age=8, name='李四'}, Person{age=10, name='张三'}, Person{age=12, name='王五'}]
    }

    public static void demo3() {
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1, 5, 4, 2);
        Collections.sort(list, new Comparator<Integer>() {
            //重写排序规则
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2; //升序
            }
        });
        System.out.println(list);  //[1, 2, 4, 5]

        //自定义类型的使用
        ArrayList<Person> list2 = new ArrayList<>();
        list2.add(new Person(10, "张三"));
        list2.add(new Person(8, "李四"));
        list2.add(new Person(12, "王五"));

        Collections.sort(list2, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge() - o2.getAge(); //按年龄升序排序
            }
        });
        System.out.println(list2);//[Person{age=8, name='李四'}, Person{age=10, name='张三'}, Person{age=12, name='王五'}]
    }
}

3.Map接口概述

Collection集合和Map集合的区别:

  • Collection中的集合,元素都是孤立存在的,像集合中存储元素采用一个个元素的方式存储。 Map中的集合,元素是成对存在的,每个元素由键和值两部分组成,通过键可以找到对应的值。
  • Collection中的集合称为单列集合,Map中的集合称为双列集合。

java.util.Map<K, V>集合,K:此映射所维护的键的类型,Y:所映射值的类型

Map集合的特点:

  1. Map集合是一个双列集合,一个元素包含两个值(key和value)。
  2. Map集合中的元素,key和value的数值类型可以相同,也可以不同。
  3. Map集合中的元素,key是不允许重复的,value是可以重复的。
  4. Map集合中的元素,key和value是一一对应的。

3.1 Map常用子类

java.util.HashMap<K, V>集合 implements Map<K, V>接口
HashMap集合的特点:

  1. HashMap集合底层是哈希表,查询的速度特别的快。
  2. HashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致。

java.util.LinkedHashMap<K, V>集合 extends HashMap<K, V>集合
LinkedHashMap集合的特点:

  1. LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)。
  2. LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序是一致的。

3.2 Map接口中的常用方法

  • public V put(K key, V value):把指定的键与指定的值添加到Map集合中。
    返回值:V,存储键值对的时候,key不重复,返回值是null;key重复,会使用新的value替换Map中重复的value,返回值为被替换的value。
  • public V remove(Object key):把指定的键所对应的键值的元素在Map集合中删除,返回被删除元素的值。
    返回值:V,key存在,返回被删除的值;key不存在,返回null。
  • public V get(Object key):根据指定的键,在Map集合中获取对应的值。
    返回值:V,key存在,返回对应的value值;key不存在,返回null。
  • boolean containsKey(Object key):判断集合中是否包含指定的键。
    包含返回true,不包含返回flase。
import java.util.HashMap;
import java.util.Map;

public class DemoMap {
    public static void main(String[] args) {
        show1();
        show2();
        show3();
        show4();
    }
    
    public static void show1(){
        Map<String, String> map = new HashMap<>();
        String s1 = map.put("猪猪侠", "小菲菲1");
        System.out.println("s1: " + s1); //s1: null
        String s2 = map.put("猪猪侠", "小菲菲2");
        System.out.println("s2: " + s2);  //s2: 小菲菲1

        System.out.println(map);  //{猪猪侠=小菲菲2}
    }

    public static void show2(){
        Map<String, Integer> map = new HashMap<>();
        map.put("猪猪侠", 120);
        map.put("小菲菲", 100);
        System.out.println(map);  //{小菲菲=100, 猪猪侠=120}

        Integer in1 = map.remove("猪猪侠");
        System.out.println("in1: " + in1);  //in1: 120
        Integer in2 = map.remove("光头强");
        System.out.println("in2: " + in2);  //in2: null

        System.out.println(map);  //{小菲菲=100}
    }

    public static void show3(){
        Map<String, Integer> map = new HashMap<>();
        map.put("猪猪侠", 120);
        map.put("小菲菲", 100);

        Integer in1 = map.get("猪猪侠");
        System.out.println("in1: " + in1);  //in1: 120
        Integer in2 = map.get("光头强");
        System.out.println("in2: " + in2);  //in2: null
    }

    public static void show4(){
        Map<String, Integer> map = new HashMap<>();
        map.put("猪猪侠", 120);
        map.put("小菲菲", 100);

        System.out.println(map.containsKey("猪猪侠"));  //true
        System.out.println(map.containsKey("熊大"));  //false
    }
}

3.3 Map集合遍历键找值方式

Map集合的第一种遍历方法:通过键找值的方法。

方法: public Set<K> keySet():获取Map集合中所有的键,存储到Set集合中。

实现步骤:

  1. 使用Map集合中的方法keySet(),把Map集合所有的key取出来,存储到一个Set集合中;
  2. 遍历Set集合,获取Map集合中的每一个key;
  3. 通过Map集合中的方法get(key),通过key找到value。
public class DemoKeySet {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("猪猪侠", 120);
        map.put("小菲菲", 100);
        map.put("超人强", 140);

        Set<String> set = map.keySet();
        //使用迭代器遍历
        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            String key = it.next();
            Integer value = map.get(key);
            System.out.println(key + "=" + value);
        }
        //使用增强for循环遍历
        for(String key : set){
            Integer value = map.get(key);
            System.out.println(key + "=" + value);
        }
    }
}

3.4 Entry键值对对象,Map集合遍历键值对方法

Map集合遍历的第二种方法:使用Entry对象遍历。

方法: public Set<Map.Entry<K, V>> entrySet():获取到Map集合中所有的键值对对象的集合(Set集合)。

Map.Entry<K, V>: 在Map接口中有一个内部接口Entry
作用: 当Map集合一创建,那么就会在Map集合中创建一个Entry对象,用来记录键和值(键值对对象,键与值的映射关系)。

实现步骤:

  1. 使用Map集合中的方法entrySet(),把Map集合内部的多个Entry对象取出来,存储到一个Set集合中;
  2. 遍历Set集合,获取Set集合中的每一个Entry对象;
  3. Entry对象中的方法getKey()获取key,getValue()获取value。
public class DemoKeySet {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("猪猪侠", 120);
        map.put("小菲菲", 100);
        map.put("超人强", 140);

        Set<Map.Entry<String, Integer>> set = map.entrySet();
        //使用迭代器遍历
        Iterator<Map.Entry<String, Integer>> it = set.iterator();
        while(it.hasNext()){
            Map.Entry<String, Integer> e = it.next();
            System.out.println(e.getKey() + "=" + e.getValue());
        }
        //使用增强for循环遍历
        for(Map.Entry<String, Integer> e : set){
            System.out.println(e.getKey() + "=" + e.getValue());
        }
    }
}

3.5 HashMap存储自定义类型键值

Map集合保证key是唯一的:作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一。

public class DemoHashMapSavePerson {
    public static void main(String[] args) {
        demo1();
        demo2();
    }
    /*key:Integer类重写了hashCode和equals方法,可以保证key唯一*/
    public static void demo1() {
        HashMap<Integer, Person> map = new HashMap<>();
        map.put(1, new Person(12, "猪猪侠"));
        map.put(2, new Person(11, "小菲菲"));
        map.put(1, new Person(13, "超人强"));

        Set<Integer> set = map.keySet();
        for(Integer key: set){
            Person value = map.get(key);
            System.out.println(value);
        }
        //Person{age=13, name='超人强'}
        //Person{age=11, name='小菲菲'}
    }

    /*key:为保证key唯一,Person类需要重写hashCode和equals方法,*/
    public static void demo2() {
        HashMap<Person, Integer> map = new HashMap<>();
        map.put(new Person(12, "猪猪侠"), 1);
        map.put(new Person(11, "小菲菲"), 2);
        map.put(new Person(12, "猪猪侠"), 3);

        Set<Map.Entry<Person, Integer>> set = map.entrySet();
        for(Map.Entry<Person, Integer> entry: set){
            Person key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key + "=" + value);
        }
    }
}
public class Person implements Comparable<Person>{
    private int age;
    private String name;
	...
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

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

3.6 LinkedHashMap集合

java.util.LinkeHashMap<K, V>集合 extends HashMap<K, V>集合

底层原理:哈希表 + 链表(记录元素顺序)。

LinkedHashMap集合:key不允许重复,有序
HashMap集合:key不允许重复,无序

3.7 Hashtable集合

java.util.Hashtable<K, V>集合 implements Map<K, V>接口

Hashtable: 底层也是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢,不能存储null值,null键;
HashMap: 底层是一个哈希表,是一个线程不安全的集合,是多线程的集合,速度快,可以存储null值,null键。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值