第八章_集合(1)_Collection集合&List&泛型

一、集合概述

  • 数组和集合的区别
    • 相同点:都是容器,可以存储多个数据
    • 不同点:
      • 数组的长度是不可变的,集合的长度是可变的
      • 数组可以存基本数据类型和引用数据类型;集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类
  • 集合类体系结构
    • 蓝色表示接口;红色表示实现类
      在这里插入图片描述

二、Collection集合

1、Collection集合概述

  • Collection集合概述

    • 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
    • JDK不提供此接口的任何直接实现;它提供更具体的子接口(如Set和List)实现
  • 创建Collection集合的对象

    • 多态的方式创建
    • 具体的实现类ArrayList
  • Collection集合常用方法

    方法名说明
    boolean add(E e)添加元素
    boolean remove(Object o)从集合中移除指定的元素
    boolean removeIf(Object o)根据条件进行移除
    void clear()清空集合中的元素
    boolean contains(Object o)判断集合中是否存在指定的元素
    boolean isEmpty()判断集合是否为空
    int size()集合的长度,也就是集合中元素的个数
import java.util.ArrayList;
import java.util.Collection;

public class MyCollectonDemo2 {
    public static void main(String[] args) {
        Collection<String> collection = new ArrayList<>();
//        boolean add(E e)		添加元素
        collection.add("aaa");
        collection.add("bbb");
        collection.add("ccc");
        collection.add("dddd");
        //System.out.println(collection);
        //method1(collection);
        //method2(collection);
        //method3(collection);
        //method4(collection);
        //method5(collection);
        //method6(collection);
    }

    private static void method6(Collection<String> collection) {
        //        int size()			集合的长度,也就是集合中元素的个数
        int size = collection.size();
        System.out.println(size);
    }

    private static void method5(Collection<String> collection) {
        //        boolean isEmpty()		判断集合是否为空
        collection.clear();
        boolean result = collection.isEmpty();
        System.out.println(result);
    }

    private static void method4(Collection<String> collection) {
        //        boolean contains(Object o)	判断集合中是否存在指定的元素
        boolean result = collection.contains("a");
        System.out.println(result);
        boolean result2 = collection.contains("aaa");
        System.out.println(result2);
    }

    private static void method3(Collection<String> collection) {
        //        void clear()			清空集合
        //就是将集合中所有的元素全部删除.
        collection.clear();
        System.out.println(collection);
    }

    private static void method2(Collection<String> collection) {
        //        boolean removeif(Object o)	根据条件进行删除
        //removeif底层会遍历集合,得到集合中的每一个元素
        //s依次表示集合中的每一个元素
        //就会把这每一个元素都到lambda表达式中去判断一下
        //如果返回的是true,则删除
        //如果返回的是false,则保留不删除.
        //boolean test(String t);
        collection.removeIf(
                (String s)->{
                    return s.length() == 3;
                }
        );
        System.out.println(collection);
    }

    private static void method1(Collection<String> collection) {
        //        boolean remove(Object o)	    从集合中移除指定的元素
        //如果删除成功了,则返回true
        //如果删除失败了,则返回false
        boolean result1 = collection.remove("aaa");
        boolean result2 = collection.remove("ddd");
        System.out.println(result1);
        System.out.println(result2);
        System.out.println(collection);
    }
}

2、Collection集合遍历

  • 迭代器介绍:迭代器,集合的专用遍历方式Iterator<E> iterator(),返回此集合中元素的迭代器,通过集合对象的iterator()方法得到
  • Iterator中的常用方法
    • boolean hasNext():判断当前位置是否有元素可以被取出
    • E next():获取当前位置的元素,将迭代器对象移向下一个索引位置
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class MyCollectonDemo3 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        //1,获得迭代器的对象
        //迭代器对象一旦被创建出来,默认指向集合的0索引处
        Iterator<String> it = list.iterator();
        //利用迭代器里面的方法进行遍历
        //当前位置是否有元素可以被取出
//        System.out.println(it.hasNext());
//        //取出当前位置的元素  + 将迭代器往后移动一个索引的位置
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}
  • 迭代器中删除的方法
    • void remove():删除迭代器对象当前指向的元素
  • for方式实现删除
    • 当集合中要删除的元素有多个并且相邻的时候,如果没有i–就无法删除干净;这个是因为集合是自动伸缩的,当删除一个元素后,被删除元素之后的元素就会向前移动
import java.util.ArrayList;

public class MyCollectonDemo4 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("b");
        list.add("c");
        list.add("d");
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            if("b".equals(s)){
                list.remove(i);
                i--;
            }
        }
        System.out.println(list);
    }
}
  • 迭代器方式实现删除
import java.util.ArrayList;
import java.util.Iterator;

public class MyCollectonDemo5 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("b");
        list.add("c");
        list.add("d");
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String s = it.next();
            if("b".equals(s)){
                //指向谁,那么此时就删除谁
                it.remove();
            }
        }
        System.out.println(list);
    }
}

3、增强for

  • 增强for介绍:是JDK5之后出现的,其内部原理是一个Iterator迭代器,简化数组和Collection集合的遍历
  • 使用限制:实现Iterable接口的类才可以使用迭代器和增强for
import java.util.ArrayList;

public class MyCollectonDemo6 {
    public static void main(String[] args) {
        ArrayList<String> list =  new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        list.add("f");
        //1,数据类型一定是集合或者数组中元素的类型
        //2,str仅仅是一个变量名而已,在循环的过程中,依次表示集合或者数组中的每一个元素
        //3,list就是要遍历的集合或者数组
        for(String str : list){
            System.out.println(str);
        }
    }
}
  • 增强for中修改第三方变量的值不会修改集合中的元素
import java.util.ArrayList;

public class MyCollectonDemo7 {
    public static void main(String[] args) {
        ArrayList<String> list =  new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for(String str : list){
            str = "q";
            System.out.println(str);
        }
        for (String s : list) {
            System.out.println(s);
        }//[a,b,c,d]

        //System.out.println(list);
    }
}
  • 三种循环的使用场景

    • 如果需要操作索引,使用普通for循环
    • 如果在遍历的过程中需要删除元素,使用迭代器
    • 如果仅仅想遍历,那么使用增强for
  • 案例:Collection集合存储学生对象并遍历

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

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
	//GET...SET...
	
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
//测试类
import java.util.ArrayList;
import java.util.Iterator;

public class MyCollectonDemo8 {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();
        Student s1 = new Student("小皮同学",23);
        Student s2 = new Student("小路同学",31);
        Student s3 = new Student("小贾同学",33);
        list.add(s1);
        list.add(s2);
        list.add(s3);
        //迭代器的方式进行遍历
        Iterator<Student> it = list.iterator();
        while(it.hasNext()){
            Student s = it.next();
            System.out.println(s);
        }
        System.out.println("-------------------------");
        //增强for
        for (Student student : list) {
            System.out.println(student);
        }
    }
}

三、List集合

1、List集合基础

  • List集合的概述
    • 有序集合,这里的有序指的是存取顺序
    • 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
    • 与Set集合不同,List允许重复的元素
  • List集合的特点:存取有序、可以重复、有索引
  • List集合的特有方法
方法名描述
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素
import java.util.ArrayList;
import java.util.List;

public class MyListDemo2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        //method1(list);
        //method2(list);
        //method3(list);
        //method4(list);
    }

    private static void method4(List<String> list) {
        //        E get(int index)		返回指定索引处的元素
        String s = list.get(0);
        System.out.println(s);
    }

    private static void method3(List<String> list) {
        //        E set(int index,E element)	修改指定索引处的元素,返回被修改的元素
        //被替换的那个元素,在集合中就不存在了.
        String result = list.set(0, "qqq");
        System.out.println(result);
        System.out.println(list);
    }

    private static void method2(List<String> list) {
        //        E remove(int index)		删除指定索引处的元素,返回被删除的元素
        //在List集合中有两个删除的方法
        //第一个 删除指定的元素,返回值表示当前元素是否删除成功
        //第二个 删除指定索引的元素,返回值表示实际删除的元素
        String s = list.remove(0);
        System.out.println(s);
        System.out.println(list);
    }

    private static void method1(List<String> list) {
        //        void add(int index,E element)	在此集合中的指定位置插入指定的元素
        //原来位置上的元素往后挪一个索引.
        list.add(0,"qqq");
        System.out.println(list);
    }
}

2、数据结构

  • 栈结构:先进后出
  • 队列结构:先进先出
  • 数组结构:查询快、增删慢
    • 查询数据通过地址值和索引定位,查询任意数据耗时相同,查询速度快
    • 删除数据时,要将原始数据删除,同时后面每个数据前移,删除效率低
    • 添加数据时,添加位置后的每个数据后移,再添加元素,添加效率极低
  • 链表:查询慢、增删快
    • 链表查询数据是否存在,必须从head开始查询
    • 查询第N个数据,也是必须从head开始查询

3、List集合的实现类

  • ArrayList底层实现:底层是数组结构实现,查询快、增删慢
  • LinkedList底层实现:底层是链表结构实现(双向链表),查询慢、增删快
  • ArrayList第一次添加元素的源码解析

在这里插入图片描述

  • LinkedList集合的特有功能

    方法名说明
    public void addFirst(E e)在该列表开头插入指定的元素
    public void addLast(E e)将指定的元素追加到此列表的末尾
    public E getFirst()返回此列表中的第一个元素
    public E getLast()返回此列表中的最后一个元素
    public E removeFirst()从此列表中删除并返回第一个元素
    public E removeLast()从此列表中删除并返回最后一个元素
import java.util.LinkedList;

public class MyLinkedListDemo4 {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        //method1(list);
        //method2(list);
        //method3(list);
        //method4(list);
    }
    private static void method4(LinkedList<String> list) {
        String first = list.removeFirst();
        System.out.println(first);
        String last = list.removeLast();
        System.out.println(last);
        System.out.println(list);
    }
    private static void method3(LinkedList<String> list) {
        String first = list.getFirst();
        String last = list.getLast();
        System.out.println(first);
        System.out.println(last);
    }
    private static void method2(LinkedList<String> list) {
        list.addLast("www");
        System.out.println(list);
    }
    private static void method1(LinkedList<String> list) {
        list.addFirst("qqq");
        System.out.println(list);
    }
}
  • LinkedList添加元素源码解析

在这里插入图片描述

四、泛型

  • 泛型的介绍:泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制
  • 泛型的好处
    • 把运行时期的问题提前到了编译期间
    • 避免了强制类型转换
  • 泛型可以使用的地方
    • 类后面 -> 泛型类
    • 方法声明上 -> 泛型方法
    • 接口后面 -> 泛型接口
  • 什么是泛型类
    • 一个类后面有,表示这个类是一个泛型类
    • 创建泛型类对象时,必须要给这个泛型确定具体的数据类型
  • 泛型的定义格式
    • <类型>:指定一种类型的格式,尖括号里面可以任意书写,一般只写一个字母。例如:
    • <类型1,类型2…>:指定多种类型的格式,多种类型之间用逗号隔开。例如: <E,T> <K,V>
泛型类
//就是一个泛型类
public class Box<E> {
    private E element;

    public E getElement() {
        return element;
    }

    public void setElement(E element) {
        this.element = element;
    }
}
测试类
/**
 * 自定义泛型类
 */
public class MyGenericityClass {
    public static void main(String[] args) {
        Box<String> box1 = new Box<>();
        box1.setElement("给小丽的土味情话");
        String element1 = box1.getElement();
        System.out.println(element1);

        Box<Integer> box2 = new Box<>();
        box2.setElement(19);
        Integer element2 = box2.getElement();
        System.out.println(element2);
    }
}
  • 泛型方法使用
import java.util.ArrayList;
import java.util.Arrays;

/**
 * 使用Java中的泛型方法
 */

public class GenericityMethod1 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("给小花同学的土味情话");
        list.add("给小丽同学的土味情话");
        list.add("给小路同学的土味情话");
        //将list集合转成一个数组并返回
        //如果是空参的,那么返回的数组类型为Object类型的.
        Object[] objects = list.toArray();
        System.out.println(Arrays.toString(objects));

        String[] strings = list.toArray(new String[list.size()]);
        System.out.println(Arrays.toString(strings));

    }
}
  • 自定义泛型方法
    • 格式:修饰符 <类型> 返回值类型 方法名(类型 变量名) { } -> public <T> void show(T t) { }
    • 泛型方法的T类型是在运行的时候确定的类型
/**
 * 自定义泛型方法
 * 定义一个泛型方法,传递一个集合和四个元素,将元素添加到集合中并返回
 */
public class GenericityMethod2 {
    public static void main(String[] args) {
        ArrayList<String> list1 = addElement(new ArrayList<String>(), "a", "b", "c", "d");
        System.out.println(list1);
        ArrayList<Integer> list2 = addElement(new ArrayList<Integer>(), 1, 2, 3, 4);
        System.out.println(list2);
    }

    public static <T> ArrayList<T> addElement(ArrayList<T> list , T t1 ,T t2 ,T t3 ,T t4){
        list.add(t1);
        list.add(t2);
        list.add(t3);
        list.add(t4);
        return list;
    }
}
  • 泛型接口定义格式修饰符 interface 接口名<类型> { }
  • 泛型接口实现类1:定义实现类时,定义和接口相同泛型,创建实现类对象时明确泛型的具体类型
  • 泛型接口实现类2:定义实现类时,直接明确泛型的具体类型
public class GenericityInterface {
    public static void main(String[] args) {
        GenericityImpl1<String> genericity = new GenericityImpl1<>();
        genericity.method("小丽给我的土味情话");

        GenericityImpl2 genericityImpl2 = new GenericityImpl2();
        genericityImpl2.method(19);
    }
}
interface Genericity<E>{
    public abstract void method(E e);
}
class GenericityImpl2 implements  Genericity<Integer>{
    @Override
    public void method(Integer integer) {
        System.out.println(integer);
    }
}
class GenericityImpl1<E> implements Genericity<E>{
    @Override
    public void method(E e) {
        System.out.println(e);
    }
}
  • 类型通配符:<?>
    • ArrayList<?>: 表示元素类型未知的ArrayList,它的元素可以匹配任何的类型;但是并不能把元素添加到ArrayList中了,获取出来的也是父类类型
  • 类型通配符上限:<? extends 类型>
    • ArrayListList <? extends Number>: 它表示的类型是Number或者其子类型
  • 类型通配符下限: <? super 类型>
    • ArrayListList <? super Number>: 它表示的类型是Number或者其父类型
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        ArrayList<Number> list2 = new ArrayList<>();
        ArrayList<Object> list3 = new ArrayList<>();
        printList(list1);
        printList(list2);

        method1(list1);
        method1(list2);
        //method1(list3);// 错误

        //method2(list1);// 错误
        method2(list2);
        method2(list3);

    }
    private static void printList(ArrayList<?> list){}

    //表示传递进来集合的类型,可以是Number类型,也可以是Number所有的子类类型
    private static void method1(ArrayList<? extends Number> list){}

    //表示传递进来集合的类型,可以是Number类型,也可以是Number所有的父类类型
    private static void method2(ArrayList<? super Number> list){}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休止符

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值