Java集合框架

集合

image-20220922200412194

image-20220922201301064

Collection接口常用的方法

image-20220922205539004

add(E e) 确保此集合包含指定的元素(可选操作)。

public class Demo01 {
    public static void main(String[] args) {
        /**
         * Collection接口常用的方法:
         * 增加:
         *          add(E e)确保此集合包含指定的元素(可选操作)。
         *          addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。
         * 修改:
         * 删除:
         *      clear()从这个集合中移除所有的元素(可选操作)。
         *      remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
         * 查看:iterator() 返回此集合中的元素的迭代器。
         * 判断:
         *         contains(Object o) 返回此集合中的元素的迭代器。
         *         equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。
         *         isEmpty() 返回 true如果集合不包含任何元素。
         */


        //通过Collection的实现类来创建对象(也就是多态)
        Collection col = new ArrayList();

        //添加add(E e)
        col.add(18);
        col.add(13);
        col.add(20);
        col.add(30);
        System.out.println(col);
    }
}

image-20220922205846242

addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。

public class Demo01 {
    public static void main(String[] args) {
        /**
         * Collection接口常用的方法:
         * 增加:
         *          add(E e)确保此集合包含指定的元素(可选操作)。
         *          addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。
         * 修改:
         * 删除:
         *      clear()从这个集合中移除所有的元素(可选操作)。
         *      remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
         * 查看:iterator() 返回此集合中的元素的迭代器。
         * 判断:
         *         contains(Object o) 返回此集合中的元素的迭代器。
         *         equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。
         *         isEmpty() 返回 true如果集合不包含任何元素。
         */


        //通过Collection的实现类来创建对象(也就是多态)
        Collection col = new ArrayList();

        //添加add(E e)
        col.add(18);
        col.add(13);
        col.add(20);
        col.add(30);
        //System.out.println(col);

        //添加addAll(Collection<? extends E> c)
        List<Integer> list = Arrays.asList(new Integer[]{20, 50, 45, 35});
        col.addAll(list);
        System.out.println(col);

    }
}

image-20220922205921408

clear()从这个集合中移除所有的元素(可选操作)。

public class Demo01 {
    public static void main(String[] args) {
        /**
         * Collection接口常用的方法:
         * 增加:
         *          add(E e)确保此集合包含指定的元素(可选操作)。
         *          addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。
         * 修改:
         * 删除:
         *      clear()从这个集合中移除所有的元素(可选操作)。
         *      remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
         * 查看:iterator() 返回此集合中的元素的迭代器。
         * 判断:
         *         contains(Object o) 返回此集合中的元素的迭代器。
         *         equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。
         *         isEmpty() 返回 true如果集合不包含任何元素。
         */


        //通过Collection的实现类来创建对象(也就是多态)
        Collection col = new ArrayList();

        //添加add(E e)
        col.add(18);
        col.add(13);
        col.add(20);
        col.add(30);
       
        //清空集合
        col.clear();

        System.out.println("集合的个数为:"+col.size());
        System.out.println("集合是否为空"+col.isEmpty()); 
   
    }
}

image-20220922210153128

contains(Object o)返回 true如果集合包含指定元素。

package cn.codesheep.test.Collection;

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

public class Demo01 {
    public static void main(String[] args) {
        /**
         * Collection接口常用的方法:
         * 增加:
         *          add(E e)确保此集合包含指定的元素(可选操作)。
         *          addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。
         * 修改:
         * 删除:
         *      clear()从这个集合中移除所有的元素(可选操作)。
         *      remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
         * 查看:iterator() 返回此集合中的元素的迭代器。
         * 判断:
         *         contains(Object o) 返回此集合中的元素的迭代器。
         *         equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。
         *         isEmpty() 返回 true如果集合不包含任何元素。
         */


        //通过Collection的实现类来创建对象(也就是多态)
        Collection col = new ArrayList();

        //添加add(E e)
        col.add(18);
        col.add(13);
        col.add(20);
        col.add(30);

        System.out.println(col);

        System.out.println("集合中的是否包含15除"+col.contains(15));

    }
}

image-20220922210919347

equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。

public class Demo01 {
    public static void main(String[] args) {
        /**
         * Collection接口常用的方法:
         * 增加:
         *          add(E e)确保此集合包含指定的元素(可选操作)。
         *          addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。
         * 修改:
         * 删除:
         *      clear()从这个集合中移除所有的元素(可选操作)。
         *      remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
         * 查看:iterator() 返回此集合中的元素的迭代器。
         * 判断:
         *         contains(Object o) 返回此集合中的元素的迭代器。
         *         equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。
         *         isEmpty() 返回 true如果集合不包含任何元素。
         */

        Collection col1 = new ArrayList();
//        List<Integer> list1 = Arrays.asList(new Integer[]{5, 4, 36, 2, 1});
//        col1.addAll(list1);
        col1.add(1);
        col1.add(2);
        col1.add(3);


        Collection col2 = new ArrayList();
//        List<Integer> list2 = Arrays.asList(new Integer[]{5, 4, 36, 2, 1});
//        col1.addAll(list2);
        col2.add(1);
        col2.add(2);
        col2.add(3);

		System.out.println("集合col1与集合col2是否相等:"+ (col1==col2));//由于col与col1是两个不同的对象,所有内存地址一定不相等
        System.out.println("集合col1与集合col2的元素是否相等:"+ col1.equals(col2));//判断集合col1与col2的元素是否相等,注意如果使用List<Integer> list2 = Arrays.asList(new Integer[]{5, 4, 36, 2, 1});往集合添加数据则这两个集合不相等

    }
}

image-20220922211011742

isEmpty() 返回 true如果集合不包含任何元素。

public class Demo01 {
    public static void main(String[] args) {
        /**
         * Collection接口常用的方法:
         * 增加:
         *          add(E e)确保此集合包含指定的元素(可选操作)。
         *          addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。
         * 修改:
         * 删除:
         *      clear()从这个集合中移除所有的元素(可选操作)。
         *      remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
         * 查看:iterator() 返回此集合中的元素的迭代器。
         * 判断:
         *         contains(Object o) 返回此集合中的元素的迭代器。
         *         equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。
         *         isEmpty() 返回 true如果集合不包含任何元素。
         */


        //通过Collection的实现类来创建对象(也就是多态)
        Collection col = new ArrayList();

        //添加add(E e)
        col.add(18);
        col.add(13);
        col.add(20);
        col.add(30);

        //添加addAll(Collection<? extends E> c)
        List<Integer> list = Arrays.asList(new Integer[]{20, 50, 45, 35});
        col.addAll(list);
        System.out.println(col);
        System.out.println("集合是否为空"+col.isEmpty());
    }
}

image-20220922211053085

remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。

public class Demo01 {
    public static void main(String[] args) {
        /**
         * Collection接口常用的方法:
         * 增加:
         *          add(E e)确保此集合包含指定的元素(可选操作)。
         *          addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。
         * 修改:
         * 删除:
         *      clear()从这个集合中移除所有的元素(可选操作)。
         *      remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
         * 查看:iterator() 返回此集合中的元素的迭代器。
         * 判断:
         *         contains(Object o) 返回此集合中的元素的迭代器。
         *         equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。
         *         isEmpty() 返回 true如果集合不包含任何元素。
         */


        //通过Collection的实现类来创建对象(也就是多态)
        Collection col = new ArrayList();

        //添加add(E e)
        col.add(18);
        col.add(13);
        col.add(20);
        col.add(30);
        System.out.println(col);

        boolean remove = col.remove(20);
        System.out.println("集合中的元素20是否已经移除:" + remove);
	    System.out.println(col);
    }
}

image-20220922211143503

size() 返回此集合中的元素的数目。

package cn.codesheep.test.Collection;

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

public class Demo01 {
    public static void main(String[] args) {
        /**
         * Collection接口常用的方法:
         * 增加:
         *          add(E e)确保此集合包含指定的元素(可选操作)。
         *          addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到这个集合(可选操作)。
         * 修改:
         * 删除:
         *      clear()从这个集合中移除所有的元素(可选操作)。
         *      remove(Object o) 从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
         * 查看:iterator() 返回此集合中的元素的迭代器。
         * 判断:
         *         contains(Object o) 返回此集合中的元素的迭代器。
         *         equals(Object o) 将指定的对象与此集合进行比较,以进行相等性。
         *         isEmpty() 返回 true如果集合不包含任何元素。
         */


        //通过Collection的实现类来创建对象(也就是多态)
        Collection col = new ArrayList();

        //添加add(E e)
        col.add(18);
        col.add(13);
        col.add(20);
        col.add(30);
        System.out.println(col);

        System.out.println("集合的个数为:"+col.size());
  
    }
}

image-20220922211226785

iterator()返回此集合中的元素的迭代器。 即遍历集合

注意:对集合进行遍历时不能用普通for循环,只能用增强for循环或while循环

public class Demo02 {
    public static void main(String[] args) {

        Collection col = new ArrayList();

        //添加add(E e)
        col.add(18);
        col.add(13);
        col.add(20);
        col.add(30);

        //对集合进行遍历时不能用普通for循环,只能用增强for循环或while循环

        //增强for循环
        for (Object o : col) {
            System.out.println(o);
        }

        System.out.println("---------------------------------");

        //while循环
        Iterator iterator = col.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
}

image-20220922212009245

Iterator的底层原理

image-20220922212313881

List接口常用的方法

image-20220923005015955

add(E e) 将指定的元素到这个列表的末尾(可选操作)。

public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);

        list.add(3,66);//向指定索引位置添加元素
        System.out.println(list);
    }
}

image-20220922213541311

set(int index, E element) 用指定元素替换此列表中指定位置的元素(可选操作)。

public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);

        list.add(3,66);//向指定索引位置添加元素
        System.out.println(list);

        //修改指定索引的元素
        list.set(3,77);
        System.out.println(list);
    }
}

image-20220922213835256

remove(int index) 移除此列表中指定位置的元素(可选操作)。

public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);

        list.add(3,66);
        System.out.println(list);

        //修改指定索引的元素
        list.set(3,77);
        System.out.println(list);

        list.remove(3);//移除索引为3的元素
        System.out.println(list);
    }
}

image-20220922214202433

remove(Object o) 从该列表中移除指定元素的第一个发生,如果它是存在的(可选操作)。

package cn.codesheep.test.List;

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

public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);
        list.remove(list.get(2));
        System.out.println(list);
    }
}

image-20220922220014871

size() 返回此列表中元素的数目。

public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);
        System.out.println("List集合的长度(集合中元素的个数):"+ list.size());

    }
}

image-20220922214752878

get(int index) 返回此列表中指定位置的元素

public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);
        Object o = list.get(2);//获取索引为2的元素
        System.out.println(o);

    }
}

image-20220922214554293

isEmpty() 返回 true如果此列表不包含元素。

public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);
        System.out.println("List集合是否为空:"+ list.isEmpty());

    }
}

image-20220922215626828

List集合的遍历

方式一:普通for循环遍历
public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);

        System.out.println("-------------------");

        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));

        }

    }
}

image-20220922215101195

方式二:增强for循环遍历
public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);

        System.out.println("-----------------------");

        for (Object o : list) {
            System.out.println(o);
        }

    }
}

image-20220922215243183

方式三:迭代器遍历
public class Demo01 {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add(13);
        list.add(17);
        list.add(16);
        list.add(10);
        list.add(-6);
        System.out.println(list);

        System.out.println("迭代器遍历");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
}

image-20220922215452004

Set接口常用的方法

image-20220923004912989

注意:set集合的元素不能重复,若添加时有重复的元素,则,只添加第一个,而且是无序的集合

add(E e) 如果没有当前(可选操作),则将指定的元素添加到该集合中。
public class Demo {
    public static void main(String[] args) {

        Set set = new HashSet<>();
        set.add(15);
        set.add(14);
        set.add(13);
        set.add(15);
        System.out.println(set);
    }
}

image-20220923001734772

注意:如果add()方法添加的内容是自定义的类,那么就不满足集合中的元素唯一了,

例如:

创建一个Student类

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

    public Student() {
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

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

测试类:

public class Test {
    public static void main(String[] args) {
        Set<Student> set = new HashSet<>();
        set.add(new Student(19,"lili"));
        set.add(new Student(20,"feifei"));
        set.add(new Student(18,"lulu"));
        set.add(new Student(17,"nana"));
        set.add(new Student(19,"lili"));
        set.add(new Student(20,"lili"));

        System.out.println("set集合的元素个数为:"+set.size());

        System.out.println(set);
    }
}

image-20220924102755625

问题:上面自定义的类型不满足唯一,无序的特点。为什么呢?

答:原因是Student类没有重写equals()方法和hashCode()方法,解决方法是在Student类重写equals()方法和hashCode()方法,添加如下的代码

@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.equals(student.age) && name.equals(student.name);
}

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

重写equals()方法和hashCode()方法后的结果

image-20220924104430516

HashSet原理图(简要原理图)

image-20220924104539946

【5】疑问:

1.数组的长度是多少。

⒉数组的类型是什么?

3.hashCode,equals方法真的调用了吗?验证4.底层表达式是什么?

5.同一个位置的数据向前放还是向后放?

6.放入数组中的数据,是直接放的吗?是否封装为对象了?l

addAll(Collection<? extends E> c) 如果没有当前(可选操作),将指定集合中的所有元素添加到该集合中。
public class Demo {
    public static void main(String[] args) {

        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);
    }
}

image-20220923001956530

clear() 从这个集合中移除所有的元素(可选操作)。
public class Demo {
    public static void main(String[] args) {
        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);

        set2.clear();
        System.out.println("----------------------");
        System.out.println("set集合的元素是否清空?" + set2);
    }
}

image-20220923002256333

contains(Object o) 如果这套 true返回包含指定的元素。
public class Demo {
    public static void main(String[] args) {

        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);

        System.out.println("-----------------------");
        boolean contains = set2.contains(23);
        System.out.println("元素23是否在Set集合中?"+ contains);

    }
}

image-20220923002531019

equals(Object o) 将指定的对象与此设置的相等性进行比较。
public class Demo {
    public static void main(String[] args) {

        Set set = new HashSet<>();
        set.add(12);
        set.add(23);
        set.add(4);
        set.add(5);
        set.add(56);
        System.out.println(set);

        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);


        System.out.println("集合set与set2是否相等?"+( set == set2));//set与set2是两个对象,内存地址不同,故不相等
        System.out.println("集合set与set2中的元素是否相等?"+set.equals(set2));

    }
}
image-20220923003105132
isEmpty() 返回 true如果这个集合不包含元素。
public class Demo {
    public static void main(String[] args) {
        
        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);
        boolean empty = set2.isEmpty();
        System.out.println("集合set2是否为空?" + empty);

    }
}
image-20220923003308361
remove(Object o) 如果当前(可选操作),则从该集合中移除指定的元素。
public class Demo {
    public static void main(String[] args) {

        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);

        boolean remove = set2.remove(23); //移除指定元素,与List不同
        System.out.println("集合set2中的元素23是否从集合中移除了?"+ remove);
        System.out.println(set2);

    }
}

image-20220923004203574

size() 返回该集合中元素个数(其基数)。
public class Demo {
    public static void main(String[] args) {

        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);
        System.out.println("集合set2的元素个数(即长度)为?" + set2.size());

    }
}

image-20220923003516782

Set集合的遍历

方式一:增强for循环遍历
public class Demo {
    public static void main(String[] args) {

        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);


        System.out.println("增强for循环遍历");
        for (Object o : set2) {
            System.out.println(o);
        }
    }
}
方式二:迭代器遍历
public class Demo {
    public static void main(String[] args) {

        Set set2 = new HashSet<>();
        List<Integer> integers = Arrays.asList(new Integer[]{12, 23, 4, 5, 56});
        set2.addAll(integers);
        System.out.println(set2);

        System.out.println("迭代器遍历");
        Iterator iterator = set2.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

LinkedHashSet实现类

特点:唯一,有序,(按照输入顺序进行输出)

public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {}
public class Demo {
    public static void main(String[] args) {
        LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add(123);
        linkedHashSet.add(456);
        linkedHashSet.add(654);
        linkedHashSet.add(321);
        linkedHashSet.add(123);
        linkedHashSet.add(213);

        System.out.println(linkedHashSet);
    }
}

image-20220924124256856

其实LinkedHashSet就是在HashSet的基础上,多了一个总的链表,这个总链表将放入的元素串在一起,方便有序的遍历

泛型

什么是泛型(Generic)?

泛型就相当于标签形式: <>

集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,
JDK1.5之后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型。

Collection, List, ArrayList这个就是类型参数,即泛型。

注意:实例化的时候不指定泛型:如果实例化的时候不明确的指定类的泛型,那么认为此泛型为object类型

//泛型类
public class GenericTest<T> {
    int age;
    String name;
    T sex;

    public void a(T n) {

    }

    public void b(T[] n) {

    }
}
class Test{
    public static void main(String[] args) {
        //GenericTest进行实例化

        //(1)实例化的时候不指定泛型:如果实例化的时候不明确的指定类的泛型,那么认为此泛型为object类型
        GenericTest genericTest = new GenericTest<>();
        genericTest.a("abc");
        genericTest.a(17);
        genericTest.a(1.7);
        genericTest.b(new String[]{"a","b","c"});


        //(2)实例化的时候指定泛型 推荐使用
        GenericTest<String> test = new GenericTest<>();
        test.sex = "男";
        test.a("abc");
        test.b(new String[]{"a","b","c"});
    }
}

泛型的继承情况

父类指定泛型的类型:指定父类泛型,那么子类就不需要再指定泛型了,可以直接使用
public class SubGenericTest extends GenericTest<Integer>{
    public static void main(String[] args) {

        //指定父类泛型,那么子类就不需要再指定泛型了,可以直接使用
        SubGenericTest test = new SubGenericTest();
        test.a(19);
    }
父类不指定泛型的类型:如果父类不指定泛型,那么子类也会变成一个泛型类,那这个E的类型可以在创建子类对象的时候确定:此时子类必须写符号
//如果父类不指定泛型,那么子类也会变成一个泛型类,那这个E的类型可以在创建子类对象的时候确定:此时子类必须写<E>符号
public class SubGenericTest2<E> extends GenericTest<E>{
    public static void main(String[] args) {
        SubGenericTest2<String> test2 = new SubGenericTest2<>();
        test2.a("abc");
        test2.sex = "女";
        test2.b(new String[]{"a","b","c"});
    }
}

应用场合

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{}

注意

(1)泛型类可以定义多个参数类型
public class MoreParamsGeneric <A,B,C>{
    A age;
    B name;
    C sex;

    public void a(A m,B n,C x) {

    }
}
(2)泛型类构造器的写法:构造器不能写泛型
public class MoreParamsGeneric <A,B,C>{
    A age;
    B name;
    C sex;

    public void a(A m,B n,C x) {

    }
    public MoreParamsGeneric(){
        
    }
}

image-20220922232920022

(3) 不同的泛型的引用类型不可以相互赋值:
public class MoreParamsGeneric <A,B,C>{
    A age;
    B name;
    C sex;

    public void a(A m,B n,C x) {

    }
    public MoreParamsGeneric(){

    }

    public void b(){
        ArrayList<String> list1 = null;
        ArrayList<Integer> list2 = null;
        list1 = list2;
    }
}

image-20220922233221699

(4)泛型如果不指定,那么就会被擦除,反应对应的类型为Object类型:

image-20220922233430624

(5)类中的静态方法不能使用类的泛型
public class MoreParamsGeneric <A,B,C>{
    A age;
    B name;
    C sex;

    public void a(A m,B n,C x) {

    }
    public MoreParamsGeneric(){

    }
    
    public static  int c(A a){
        return 10;
    }
}

image-20220922233733709

(6)不能直接使用E[]来创建数组的泛型

错误的写法:

 public  void c(A m,B n,C x){
       A[]a =new A[10];
    }

正确的写法,且只能这样写

public  void c(A m,B n,C x){
       A[] a =(A[])new Object[10];
    }

什么是泛型方法?

不是带泛型的方法就是泛型方法

泛型方法有要求:这个方法的泛型的参数类型要和当前的类的泛型无关换个角度:

泛型方法对应的那个泛型参数类型和当前所在的这个类是否是泛型类,与泛型是啥无关

public class GenericFunction <E>{
    
    //不是泛型方法
    public void a(E e){
        
    }
    
    //泛型方法
    public <T> void b(T t){
        
    }
}

泛型方法定义的时候,要在方法名前加上

原因:如果不加的话,会把T当做一种数据类型,然而代码中没有T类型那么就会报错

T的类型是在调用方法的时候确定的

public class GenericFunction <E>{

    //不是泛型方法
    public void a(E e){

    }

    //泛型方法
    public <T> void b(T t){

    }

}
class Demo{
    public static void main(String[] args) {
        GenericFunction<String> genericFunction = new GenericFunction<>();
        genericFunction.a("zbc");
        genericFunction.b(123);
    }
}

image-20220922235652711

注意:泛型方法可以是静态方法

image-20220922235822310

总结: 若A和B是子类与父类的关系,但是G和G不存在继承关系的。

例如

public class GenericTest1 {

    public static void main(String[] args) {


        //多态:父类引用指向子类对象
        Object o = new Object();
        String s = new String();
        o = s;

        //多态:父类引用指向子类对象
        Object[] objects = new Object[10];
        String[] str = new String[10];
        objects = str;

        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        list1 = list2;
    }
}

image-20220923122346669

泛型的通配符(?)

在没有通配符的时候:

下面的a方法,相当于方法的重复定义,会报错

public class Demo1 {
    public void a(List<Object> list){}
    public void a(List<String> list){}
    public void a(List<Integer> list){}
}

image-20220923123237752

引入通配符(?)
public class Demo1 {
 
    public static void main(String[] args) {
        ArrayList<Object> obj = new ArrayList<>();
        ArrayList<String> str = new ArrayList<>();
        ArrayList<Integer> arrayList = new ArrayList<>();
        
        List<?> list = null;
        list = obj;
        list = str;
        list = arrayList;
        
    }
}

发现:A和B是子类与父类的关系,G和G不存在子类与父类关系,是并列的,加入通配符?后,G<?>就变成了G和G的父类

使用通配符
public class Demo1 {
    public void a(List<?> list){
        //内部遍历的时候使用Object即可,不要用?
        for (Object o : list) {
            System.out.println(o);
        }
    }

    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        demo1.a(new ArrayList<Integer>());
        demo1.a(new ArrayList<String>());
        demo1.a(new ArrayList<Object>());
    }
}

注意:

  • 写输入数据时不能随意添加数据,list.add(null),add中的数据不能随意添加
  • 数据读取使用Object类型来接收,Object obj = list.get(0);

泛型的受限

public class Person {
}
public class Student extends Person{
}
public class Test1 {
    public static void main(String[] args) {

        //这三个集合时并列的关系,不存在继承的关系
        List<Object> a = new ArrayList<>();
        List<Person> b = new ArrayList<>();
        List<Student> c = new ArrayList<>();

        /*使用泛型受限:
               泛型上限:
                    List<? extends Person>相当于,List<? extends Person>是 List<Person>的父类,是 List<Person的子类(Student)>的父类


               泛型下限:
                     List<? super Person>相当于,List<? super Person>是 List<Person>的父类,是 List<Person父类(Object)>的父类
		 */
        /*List<? extends Person> list = null;
        list = a;
        list = b;
        list = c;*/

        List<? super Person> list = null;
        list = a;
        list = b;
        list = c;
    }
}

LinkedList常用的方法

image-20220923131312341

返回值Method and Description
booleanadd(E e) 将指定的元素列表的结束。
voidadd(int index, E element) 在列表中指定的位置上插入指定的元素。
booleanaddAll(Collection<? extends E> c) 追加指定集合的所有元素到这个列表的末尾,按他们的指定集合的迭代器返回。
booleanaddAll(int index, Collection<? extends E> c) 将指定集合中的所有元素插入到该列表中,从指定位置开始。
voidaddFirst(E e) 在此列表的开始处插入指定的元素。
void
voidclear() 从这个列表中移除所有的元素。
Objectclone() 返回该 LinkedList浅拷贝。
booleancontains(Object o) 返回 true如果这个列表包含指定元素。
Iterator<E>descendingIterator() 返回在反向顺序在deque容器元素的迭代器。
Eelement() 检索,但不删除,此列表的头(第一个元素)。
Eget(int index) 返回此列表中指定位置的元素。
EgetFirst() 返回此列表中的第一个元素。
EgetLast() 返回此列表中的最后一个元素。
intindexOf(Object o) 返回此列表中指定元素的第一个出现的索引,或-如果此列表不包含元素,或- 1。
intlastIndexOf(Object o) 返回此列表中指定元素的最后一个发生的索引,或-如果此列表不包含元素,或- 1。
ListIterator<E>listIterator(int index) 返回此列表中元素的列表迭代器(在适当的顺序),从列表中的指定位置开始。
booleanoffer(E e) 将指定的元素添加到列表的尾部(最后一个元素)。
booleanofferFirst(E e) 在列表的前面插入指定的元素。
booleanofferLast(E e) 在列表的结尾插入指定的元素。
Epeek() 检索,但不删除,此列表的头(第一个元素)。
EpeekFirst() 检索,但不删除该列表的第一个元素,或返回 null如果这个列表是空的。
EpeekLast() 检索,但不删除该列表的最后一个元素,或返回 null如果这个列表是空的。
Epoll() 检索并删除此列表的头(第一个元素)。
EpollFirst() 检索并移除此列表的第一个元素,或返回 null如果这个列表是空的。
EpollLast() 检索并移除此列表的最后一个元素,或返回 null如果这个列表是空的。
Epop() 从这个列表所表示的堆栈中弹出一个元素。
voidpush(E e) 将一个元素推到由该列表所表示的堆栈上。
Eremove() 检索并删除此列表的头(第一个元素)。
Eremove(int index) 移除此列表中指定位置的元素。
booleanremove(Object o) 从该列表中移除指定元素的第一个发生,如果它是存在的。
EremoveFirst() 移除并返回此列表中的第一个元素。
booleanremoveFirstOccurrence(Object o) 删除此列表中指定元素的第一个出现(当遍历从头到尾的列表)。
EremoveLast() 移除并返回此列表中的最后一个元素。
booleanremoveLastOccurrence(Object o) 删除此列表中指定元素的最后一次(当遍历从头到尾的列表时)。
Eset(int index, E element) 用指定元素替换此列表中指定位置的元素。
intsize() 返回此列表中元素的数目。
Spliterator<E>spliterator() 创建一个后期绑定和快速失败 Spliterator超过此列表中的元素。
Object[]toArray() 返回一个数组,包含在这个列表中的所有元素在适当的顺序(从第一个到最后一个元素)。
<T> T[]toArray(T[] a) 返回一个数组,包含在这个列表中的所有元素在适当的顺序(从第一到最后一个元素);返回数组的运行时类型是指定的数组的运行时类型。

大部分的方法与Collection、List、Se的方法类似,这里只写出与其他三种方法不同的方法

add(int index, E element) 在列表中指定的位置上插入指定的元素。

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);

        linkedList.add(2,"6666");
        System.out.println("--------------------");
        System.out.println(linkedList);

    }
}

image-20220923201832084

addFirst(E e) 在此列表的开始处插入指定的元素。

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);

        linkedList.add(2,"6666");
        System.out.println("--------------------");
        System.out.println(linkedList);


        linkedList.addFirst("123");
        System.out.println("--------------------");
        System.out.println(linkedList);


    }
}

image-20220923204118995

addLast(E e) 将指定的元素列表的末尾。

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);

        linkedList.addLast("456");
        System.out.println("--------------------");
        System.out.println(linkedList);

        System.out.println(linkedList.getFirst());

    }
}

image-20220923204250882

getFirst() 返回此列表中的第一个元素。

package cn.codesheep.test.LinkedList;

import java.util.LinkedList;

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);


        linkedList.addLast("456");
        System.out.println("--------------------");
        System.out.println(linkedList);

        System.out.println(linkedList.getFirst());


    }
}

image-20220923204428167

getLast() 返回此列表中的最后一个元素。

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);


        System.out.println(linkedList.getLast());

    }
}

image-20220923204628607

element() 检索,但不删除,此列表的头(第一个元素)。即获取列表的第一个元素,与getFirst()的作用一致

package cn.codesheep.test.LinkedList;

import java.util.LinkedList;

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);

        String element = linkedList.element();
        System.out.println(element);

    }
}

image-20220923205033230

offer(E e) 将指定的元素添加到列表的尾部(最后一个元素)。

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);


        linkedList.offer("王炸");
        System.out.println(linkedList);
    }
}

image-20220923205228996

offerFirst(E e) 在列表的前面插入指定的元素。

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);

        linkedList.offerFirst("张三");
        System.out.println(linkedList);

    }
}

image-20220923205417004

offerLast(E e) 在列表的结尾插入指定的元素。

package cn.codesheep.test.LinkedList;

import java.util.LinkedList;

public class Demo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("abc");
        linkedList.add("bcd");
        linkedList.add("cde");
        linkedList.add("def");
        linkedList.add("efg");
        System.out.println(linkedList);
        
        linkedList.offerLast("最后的元素");
        System.out.println(linkedList);

    }
}

image-20220923205712780

ArrayList的数据结构

物理结构:紧密结构

逻辑结构:线性表(数组)

LinkedList的数据结构

物理结构:跳转结构

逻辑结构:线性表(链表)

LinkedList的底层数据结构是双向链表

image-20220923231911799

模拟LinkedList源码

创建一个Node类
public class Node {  //节点类
    //三个属性:上一个元素地址,当前元素地址,下一个元素地址

    //上一个元素地址
    private Node pre;

    //当前元素地址
    private Object obj;

    //下一个元素地址
    private Node next;

    public Node() {
    }

    public Node(Node pre, Object obj, Node next) {
        this.pre = pre;
        this.obj = obj;
        this.next = next;
    }

    public Node getPre() {
        return pre;
    }

    public void setPre(Node pre) {
        this.pre = pre;
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" +
                "pre=" + pre +
                ", obj=" + obj +
                ", next=" + next +
                '}';
    }
}
创建一个MyLinkedList类
//链中一定有一个首节点和一个未节点
public class MyLinkedList {

    //首节点
    Node first;

    //未节点
    Node last;

    //计数器
    int count = 0;


    //提供一个无参构造器
    public MyLinkedList() {
    }

    //添加元素的方法
    public void add(Object o){
        if (first == null){//证明你添加的元素是第一个节点:
            //将添加的元素封装为一个Node对象
            Node n = new Node();
            n.setPre(null);
            n.setObj(o);
            n.setNext(null);

            //当前链中第一个节点变为n
            first = n;

            //当前链中最后一个节点变为n
            last = n;
        }else {
            //证明已经不是链中第一个节点了
            Node node = new Node();
            node.setPre(last); //node的上一个节点一定是当前链中的最后一个节点last

            node.setObj(o);
            node.setNext(null);

            //当前链中的最后一个节点的下一个元素要指向node
            last.setNext(node);

            //将最后一个节点变为node
            last = node;

        }

        //链表中元素数量加1
        count++;

    }

    //获取集合中元素的数量
    public int getSize(){
        return count;
    }

    //通过下标获取到链表的元素
    public Object get(int index){
        //获取链表的头节点元素
        Node n = first;
        for (int i = 0; i < index; i++) {
            //一路next得到想要的元素
            n = n.getNext();
        }
        return n.getObj();

    }
}
测试类
public class Test {
    public static void main(String[] args) {
        MyLinkedList linkedList = new MyLinkedList();
        linkedList.add("aaa");
        linkedList.add("bbb");
        linkedList.add("ccc");

        System.out.println(linkedList.getSize());

        System.out.println(linkedList.get(2));
    }
}

image-20220923235652141

iterator(),Iterator,Iterable的关系

image-20220924001503112

迭代器中的hasNext(),Next()的具体实现

image-20220924002407926

ListIterator

在集合中某个元素后添加元素

public class TestListIterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");

        //使用iterator遍历集合并在元素cc后添加kk元素
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            if ("cc".equals(iterator.next())){
                list.add("kk");
            }
        }
    }
}

使用iterator()方法来实现,会报如下的错误,不可行,此时需要用

image-20220924003651691

使用listIterator()方法来实现,

package cn.codesheep.test.LinkedList;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class TestListIterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        System.out.println(list);
        
        ListIterator<String> it = list.listIterator();
        while (it.hasNext()){
            if ("cc".equals(it.next())){
                it.add("kk");
            }
        }
        System.out.println("---------------------");
        System.out.println(list);
    }
}

image-20220924004637272

listIterator()的逆向遍历

public class TestListIterator {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        System.out.println(list);

        ListIterator<String> it = list.listIterator();
        while (it.hasNext()){
            if ("cc".equals(it.next())){
                it.add("kk");
            }
        }
        System.out.println("---------------------");
        System.out.println(list);


        //listIterator()的逆向遍历
        System.out.println(it.hasPrevious());//是否有上一个元素
        while (it.hasPrevious()){
            System.out.println(it.previous());
        }

        System.out.println(it.hasPrevious());//是否有上一个元素
    }
}

image-20220924005647321

比较器

比较int类型

**比较的思路:**将比较的数据做差,然后返回一个int类型的数据,将这个int类型的数值与0进行比较,结果的可能性有,> 0,< 0,= 0

public class Demo {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = a - b;
        System.out.println(c);
    }
}

比较String类型

String类实现了Comparable接口,这个接口中有一个抽象方法compareTo,String类中重写这个方法即可

public interface Comparable<T> {
    public int compareTo(T o);
}
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
     public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }
}
public class Demo {
    public static void main(String[] args) {
        String a = "A";
        String b = "B";
        System.out.println(a.compareTo(b));
    }
}

比较Double类型

public class Demo {
    public static void main(String[] args) {
        double a = 9.3;
        double b = 9.6;
        //System.out.println((int)(a-b));//由于double的精度问题,此方法不可行,只能转换成对应的包装类,通过compareTo()方法进行比较
        System.out.println(((Double) a).compareTo((Double) b));
    }
}

比较自定义的数据类型

内部比较器

创建一个Student类

public class Student implements Comparable<Student>{
    private Integer age;
    private String name;
    private Double height;

    public Student() {
    }

    public Student(Integer age, String name, Double height) {
        this.age = age;
        this.name = name;
        this.height = height;
    }

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

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

    @Override//比较器
    public int compareTo(Student o) {

        //比较学生的年龄
        //return this.getAge() - o.getAge();

        //比较学生的身高
        //return ((Double)(this.getHeight())).compareTo((Double)(o.getHeight()));

        //比较学生的名字
        return this.getName().compareTo(o.getName());
    }
}

测试类

public class Test {
    public static void main(String[] args) {

        //比较学生信息
        Student s1 = new Student(10, "lili", 160.5);
        Student s2 = new Student(15, "nana", 170.5);
        System.out.println(s1.compareTo(s2));
    }
}
外部比较器(推荐使用),可以使用多态,拓展性好
public class ExternalCompare implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {

        //比较两个学生的年龄
       // return o1.getAge() - o2.getAge();

        //比较两个学生的名字
        return o1.compareTo(o2);
        
        //在年龄相同的情况下比较身高,否则就比较年龄
        if (o1.getAge() == o2.getAge()){
            return ((Double)o1.getHeight()).compareTo((Double) (o2.getHeight()));
        }else {
            return o1.getAge() - o2.getAge();
        }

    }
}

测试类

public class Test {
    public static void main(String[] args) {

        /**
         * 使用外部比较器
         */

       Comparator com = new ExternalCompare();//多态的写法
        Student s1 = new Student(10, "lili", 160.5);
        Student s2 = new Student(15, "nana", 170.5);
        System.out.println(com.compare(s1,s2));
    }
}

TreeSet

存入Integer数据(底层利用的是内部比较器)

image-20220924225313878

特点:数据唯一,并按添加的元素进行升序排列

public class Demo {
    public static void main(String[] args) {
        TreeSet<Integer> ts = new TreeSet<>();
        ts.add(12);
        ts.add(15);
        ts.add(9);
        ts.add(3);
        ts.add(4);
        ts.add(12);

        System.out.println(ts.size());
        System.out.println(ts);
    }
}

image-20220924134345772

原理:底层原理是用二叉树来实现(遍历方式是中序遍历)

image-20220924141052630

存入String类型的数据(底层利用的也是内部比较器)

image-20220924225216912

public class Test01 {
    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<>();
        treeSet.add("alili");
        treeSet.add("zlili");
        treeSet.add("ylili");
        treeSet.add("flili");
        treeSet.add("hlili");
        treeSet.add("mlili");
        treeSet.add("alili");
        System.out.println(treeSet);
    }
}

image-20220924224539479

存入自定义的Student类型的数据

利用内部比较器实现:

Student类

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

    public Student() {
    }

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

    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;
    }

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

    //内部比较器
    @Override
    public int compareTo(Student o) {

        //比较学生的年龄
        return this.getAge() - o.getAge();
    }
}

测试类

public class Test02 {
    public static void main(String[] args) {

        TreeSet<Student> set = new TreeSet<>();
        set.add(new Student(19,"lili"));
        set.add(new Student(20,"lili"));
        set.add(new Student(10,"lili"));
        set.add(new Student(30,"lili"));
        set.add(new Student(9,"lili"));
        set.add(new Student(3,"lili"));

        System.out.println(set.size());
        System.out.println(set);


    }
}
利用外部比较器实现:

Student类

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

    public Student() {
    }

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

    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;
    }

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

}

外部比较器

public class ExternalCompare implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getAge() - o2.getAge();
    }
}

测试类

public class Test02 {
    public static void main(String[] args) {

        //利用外部比较器必须自己指定
        //一旦指定外部比较器,那么就会按照外部比较器来比较
        //方法一
//        Comparator<Student> compare = new ExternalCompare();

        //方法二
        /*Comparator<Student> compare = new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }

        };*/

//        TreeSet<Student> set = new TreeSet<>(compare);
        //方法三
        TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }

        });
        set.add(new Student(19,"lili"));
        set.add(new Student(20,"lili"));
        set.add(new Student(10,"lili"));
        set.add(new Student(30,"lili"));
        set.add(new Student(9,"lili"));
        set.add(new Student(3,"lili"));

        System.out.println(set.size());
        System.out.println(set);


    }
}

Map集合

image-20220925205322395

Modifier and TypeMethod and Description
voidclear() 从这个映射中移除所有的映射(可选操作)。
default Vcompute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 试图计算出指定键和当前的映射值的映射(或 null如果没有当前映射)。
default VcomputeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) 如果指定的键是不是已经与价值相关的(或映射到 null),尝试使用给定的映射功能,进入到这个Map除非 null计算其价值。
default VcomputeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 如果指定键的值是存在和非空的,尝试计算一个新的映射,给出了键和它当前的映射值。
booleancontainsKey(Object key) 返回 true如果这Map包含一个指定的键映射。
booleancontainsValue(Object value) 返回 true如果映射到指定的值的一个或多个键。
Set<Map.Entry<K,V>>entrySet() 返回一个 Set视图的映射包含在这个Map。
booleanequals(Object o) 将指定的对象与此映射的相等性进行比较。
default voidforEach(BiConsumer<? super K,? super V> action) 在该映射中的每个条目执行给定的操作,直到所有的条目被处理或操作抛出异常。
Vget(Object key) 返回指定的键映射的值,或 null如果这个Map不包含的键映射。
default VgetOrDefault(Object key, V defaultValue) 返回指定的键映射的值,或 defaultValue如果这个Map不包含的键映射。
inthashCode() 返回此映射的哈希代码值。
booleanisEmpty() 返回 true如果这个Map不包含键值的映射。
Set<K>keySet() 返回一个 Set的关键视图包含在这个Map。
default Vmerge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) 如果指定的键已与值相关联的值或与空值相关联的,则将其与给定的非空值关联。
Vput(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)。
voidputAll(Map<? extends K,? extends V> m) 从指定的映射到这个Map(可选操作)复制所有的映射。
default VputIfAbsent(K key, V value) 如果指定的键是不是已经与价值相关的(或映射到 null)将其与给定的值并返回 null,否则返回当前值。
Vremove(Object key) 如果存在(可选操作),则从该Map中移除一个键的映射。
default booleanremove(Object key, Object value) 仅当它当前映射到指定的值时,为指定的键移除条目。
default Vreplace(K key, V value) 仅当它当前映射到某一值时,替换指定的键的条目。
default booleanreplace(K key, V oldValue, V newValue) 仅当当前映射到指定的值时,替换指定的键的条目。
default voidreplaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为在该项上调用给定函数的结果,直到所有的条目都被处理或函数抛出异常。
intsize() 返回这个映射中的键值映射的数目。
Collection<V>values() 返回一个 Collection视图的值包含在这个Map。

Map常用的方法

put(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)。
public class Demo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",34563456);
        map.put("lili",345673456);
        map.put("mingming",123456789);
        System.out.println(map.size());
        System.out.println(map);
    }
}

image-20220925000146376

clear() 从这个映射中移除所有的映射(可选操作)。
public class Demo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",34563456);
        map.put("lili",345673456);
        map.put("mingming",123456789);
        System.out.println(map.size());
        System.out.println(map);

        map.clear();

        System.out.println("=============================");
        System.out.println(map);
    }
}

image-20220925000640889

remove(Object key) 如果存在(可选操作),则从该Map中移除一个键的映射。
public class Demo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",34563456);
        map.put("lili",345673456);
        map.put("mingming",123456789);
        System.out.println(map.size());
        System.out.println(map);

        map.remove("mingming");
        System.out.println("=======================");
        System.out.println(map);
    }
}

image-20220925000940251

containsKey(Object key) 返回 true如果这Map包含一个指定的键映射。
public class Demo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",34563456);
        map.put("lili",345673456);
        map.put("mingming",123456789);
        System.out.println(map.size());
        System.out.println(map);

        System.out.println(map.containsKey("lili"));

    }
}

image-20220925001328844

containsValue(Object value) 返回 true如果映射到指定的值的一个或多个键。
public class Demo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",123456789);
        map.put("lili",345673456);
        map.put("mingming",123456789);
        System.out.println(map.size());
        System.out.println(map);

        System.out.println(map.containsValue(123456789));

    }
}

image-20220925001501361

entrySet() 返回一个 Set视图的映射包含在这个Map。 即获取map集合中的所有key和value
public class Test01 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",123456789);
        map.put("lili",345673456);
        map.put("mingming",123456789);

        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            System.out.println(entry);
        }
    }
}

image-20220925003211258

get(Object key) 返回指定的键映射的值,或 null如果这个Map不包含的键映射。
public class Test01 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",123456789);
        map.put("lili",345673456);
        map.put("mingming",123456789);

        System.out.println(map.get("lili"));
    }
}
keySet() 返回一个 Set的关键视图包含在这个Map。即获取map集合中所有的key
public class Test01 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",123456789);
        map.put("lili",345673456);
        map.put("mingming",123456789);
        Set<String> strings = map.keySet();
        for (String string : strings) {
            System.out.println(string);
        }
    }
}
image-20220925002630156
values() 返回一个 Collection视图的值包含在这个Map。 即获取map集合中所有的value
public class Test01 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",123456789);
        map.put("lili",345673456);
        map.put("mingming",123456789);

        Collection<Integer> values = map.values();
        for (Integer value : values) {
            System.out.println(value);
        }
    }
}

image-20220925002800499

equals(Object o) 将指定的对象与此映射的相等性进行比较。
public class Test01 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",123456789);
        map.put("lili",345673456);
        map.put("mingming",123456789);

        Map<String,Integer> map1 = new HashMap<>();
        map1.put("lili",10101010);
        map1.put("nana",12345234);
        map1.put("feifei",123456789);
        map1.put("lili",345673456);
        map1.put("mingming",123456789);

        System.out.println(map == map1);//判断map与map1的内存地址是否相等
        System.out.println(map.equals(map1));//判断map与map1中的元素是否相等
    }
}
isEmpty() 返回 true如果这个Map不包含键值的映射。
public class Test01 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("lili",10101010);
        map.put("nana",12345234);
        map.put("feifei",123456789);
        map.put("lili",345673456);
        map.put("mingming",123456789);


        System.out.println(map.isEmpty());
    }
}

TreeMap

  • 特点:唯一,有序(按照升序或降序排列)

  • 原理:二叉树,key遵循二叉树的特点,放入集合的数据对应的类型一定要实现比较器(内部比较器或外部比较器)

key的类型是String类型
public class test {
    public static void main(String[] args) {
        Map<String, Integer> map = new TreeMap<>();
        map.put("alili",123);
        map.put("glili",321);
        map.put("clili",213);
        map.put("blili",132);
        System.out.println(map.size());
        System.out.println(map);
    }
}

image-20220925104715479

key的类型是一个自定义的引用数据类型(Student)

此时必须要实现比较器(内部比较器或外部比较器),要不然就会报如下的错误

image-20220925105513966

实现内部比较器(Comparable)

Student类

public class Student implements Comparable<Student>{
    private int age;
    private String name;
    private double height;

    public Student() {
    }

    public Student(int age, String name, double height) {
        this.age = age;
        this.name = name;
        this.height = height;
    }

    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 double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

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

    @Override
    public int compareTo(Student o) {
        //按年龄进行排序
        /*return this.getAge() - o.getAge();*/

        //按名字进行排序】
        //return this.getName().compareTo(o.getName());

        //按身高进行排序
        return ((Double)(this.getHeight())).compareTo((Double)(o.getHeight()));
    }
}

测试类

public class Test02 {
    public static void main(String[] args) {
          Map<Student, Integer> map = new TreeMap<>();
          map.put(new Student(19,"lili",170.5),1001);
          map.put(new Student(18,"nana",171.5),1002);
          map.put(new Student(19,"lili",170.5),1023);
          map.put(new Student(19,"lili",170.5),1009);
          map.put(new Student(19,"lili",170.5),1011);

        System.out.println(map.size());

        System.out.println(map);
    }
}

image-20220925114655039

image-20220925114800505

image-20220925114928893

实现外部比较器
public class ExternalCompare implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        //将年龄作为key进行排序
       // return o1.getAge() - o2.getAge();
        
        
        //将身高作为key进行排序
//        return ((Double) o1.getHeight()).compareTo((Double) (o2.getHeight()));
        
        //以名字作为key进行排序
        return o1.getName().compareTo(o2.getName());
    }
}

测试类

public class Test02 {
    public static void main(String[] args) {

       /* Map<Student, Integer> map = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //将年龄作为key进行排序
                // return o1.getAge() - o2.getAge();


                //将身高作为key进行排序
                //return ((Double) o1.getHeight()).compareTo((Double) (o2.getHeight()));

                //以名字作为key进行排序
                return o1.getName().compareTo(o2.getName());
            }
        });*/
        
          Comparator<Student> comparator = new ExternalCompare();
          Map<Student, Integer> map = new TreeMap<>(comparator);
          map.put(new Student(19,"lili",170.5),1001);
          map.put(new Student(18,"nana",171.5),1002);
          map.put(new Student(15,"anan",178.5),1023);
          map.put(new Student(56,"juju",175.5),1009);
          map.put(new Student(25,"lili",176.5),1011);

        System.out.println(map.size());

        System.out.println(map);
    }
}

HashMap

重要属性

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
    
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //定义了一个16,一会要赋给数组的长度
    static final int MAXIMUM_CAPACITY = 1 << 30; 
    static final float DEFAULT_LOAD_FACTOR = 0.75f;  //定义了一个值:0.75负载因子,加载因子
    transient Node<K,V>[] table;//底层主数组
    transient int size;//添加的元素的数量
    int threshold;//定义个变量,没赋值默认为0 ,-->这个变量是用来表示数组扩容的边界值,门槛值
    final float loadFactor;//这个变量用来接收:装填因子,负载因子,加载因子
    
    
    //无参构造器
    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }
    
    //有参构造器
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }

}
    

Collections工具类

public class Demo {
    public static void main(String[] args) {


        //Collections不支持创建对象,因为构造器私有化了
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("vv");
        list.add("cc");
        Collections.addAll(list,"dd","ee","zz");
        Collections.addAll(list,new String[]{"kk","jj","mm"});
        System.out.println(list);


        //binarySearch必须在有序集合中查找
        Collections.sort(list);//升序排列
        System.out.println(list);

        //二分查找
        System.out.println(Collections.binarySearch(list, "ee"));

        System.out.println("=========================================");

        //copy
        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1,"tt","ss");
        Collections.copy(list,list1);//将list1的内容替换到list上的对应位置

        System.out.println(list);
        System.out.println(list1);


        System.out.println("==============================================");
        //fill用指定元素替换指定列表的所有元素
        Collections.fill(list1,"zzz");//用zzz替换指定列表list1中的所有元素
        System.out.println(list1);
    }
}
      Comparator<Student> comparator = new ExternalCompare();
      Map<Student, Integer> map = new TreeMap<>(comparator);
      map.put(new Student(19,"lili",170.5),1001);
      map.put(new Student(18,"nana",171.5),1002);
      map.put(new Student(15,"anan",178.5),1023);
      map.put(new Student(56,"juju",175.5),1009);
      map.put(new Student(25,"lili",176.5),1011);

    System.out.println(map.size());

    System.out.println(map);
}

}






### HashMap

重要属性

```java
public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
    
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //定义了一个16,一会要赋给数组的长度
    static final int MAXIMUM_CAPACITY = 1 << 30; 
    static final float DEFAULT_LOAD_FACTOR = 0.75f;  //定义了一个值:0.75负载因子,加载因子
    transient Node<K,V>[] table;//底层主数组
    transient int size;//添加的元素的数量
    int threshold;//定义个变量,没赋值默认为0 ,-->这个变量是用来表示数组扩容的边界值,门槛值
    final float loadFactor;//这个变量用来接收:装填因子,负载因子,加载因子
    
    
    //无参构造器
    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }
    
    //有参构造器
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }

}
    

Collections工具类

public class Demo {
    public static void main(String[] args) {


        //Collections不支持创建对象,因为构造器私有化了
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("vv");
        list.add("cc");
        Collections.addAll(list,"dd","ee","zz");
        Collections.addAll(list,new String[]{"kk","jj","mm"});
        System.out.println(list);


        //binarySearch必须在有序集合中查找
        Collections.sort(list);//升序排列
        System.out.println(list);

        //二分查找
        System.out.println(Collections.binarySearch(list, "ee"));

        System.out.println("=========================================");

        //copy
        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1,"tt","ss");
        Collections.copy(list,list1);//将list1的内容替换到list上的对应位置

        System.out.println(list);
        System.out.println(list1);


        System.out.println("==============================================");
        //fill用指定元素替换指定列表的所有元素
        Collections.fill(list1,"zzz");//用zzz替换指定列表list1中的所有元素
        System.out.println(list1);
    }
}

image-20220925172816182

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值