JavaSE# 笔记【 Collection集合 Iterator迭代器 增强for循环 泛型 List接口】@Gray

第一章 Collection集合

1.集合和数组的区别

数组:int[] arr = new int[3];

1、数组是引用类型。

2、数组长度是固定

3、数组可以按照索引进行查找。

4、数组可以定义为保存任意类型的数组。int[] arr = new int[3]; String[] strs = new String[3]; Student[] stus = new Student[3];

集合: ArrayList arr = new ArrayList();

1、集合是引用类型。

2、集合长度可变。

3、集合可以按照索引进行查找。

4、集合可以添加任何类型的数据(必须是引用类型)。使用泛型约束。

ArrayList arr = new ArrayList<>(); //报错

ArrayList arr = new ArrayList<>(); //可以

ArrayList arr = new ArrayList<>(); //可以

ArrayList arr = new ArrayList<>(); //可以

简单的说:

1、集合是动态数组。(长度可变、也可以按照索引查询)

2、集合可以添加任何类型数据,但使用泛型约束。

import java.util.ArrayList;

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

        //泛型起到了约束添加数据类型的作用。
        ArrayList<String> list = new ArrayList();
        list.add("aaa");
        list.add("bbb");
        //list.add(10); // new Integer(10);

        for (int i = 0; i < list.size(); i++) {
            String s = (String) list.get(i); //取值就不会出现返回类型不一样的问题
            System.out.println(s);
        }

    }
}

2.集合概述

Collection 是集合层次结构中的根接口。Collection 可以保存一组对象,这些对象也称为元素。

一些 collection 允许有重复的元素,而另一些则不允许。(子接口或实现类)

一些 collection 是有序的,而另一些则是无序的。(子接口或实现类)

3.集合常用类的继承体系

在这里插入图片描述

4.Collection集合常用方法

方法说明
boolean add(E e)添加元素到集合中
int size()获取集合的长度
boolean remove(Object e)删除集合中的某个元素
boolean contains(Object obj)判断集合是否包含某个元素
Object[] toArray() 了解把集合转成Object[]类型
public void clear() 了解清空集合中所有的元素。
public boolean isEmpty()判断当前集合是否为空。

示例代码:

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

/*
    Collection集合的常用方法
    boolean add(E e)添加元素到集合中
    int size()获取集合的长度
    boolean remove(Object e) 删除集合中的某个元素
    boolean contains(Object obj)判断集合是否包含某个元素
    Object[] toArray()  把集合转成Object[]类型
    public void clear() 清空集合中所有的元素。
    public boolean isEmpty()    判断当前集合是否为空。
 */
public class TestCollection {
    public static void main(String[] args) {
        //创建一个集合对象
        Collection<String> coll = new ArrayList<>();

        //添加元素到集合中
        // coll.add("宋吉吉");
        // coll.add("王蓉");
        // coll.add("马宝强");

        //删除集合中的某个元素
        // boolean bb = coll.remove("宋吉吉");
        // System.out.println(bb);

        //判断集合是否包含某个元素
        /*boolean b = coll.contains("宋吉吉");
        if(b){ //b==true
            System.out.println("这样不好");
        }else{
            System.out.println("没有什么事");
        }*/

        //把集合转成Object[]类型
        // Object[] objs = coll.toArray();
        // System.out.println(Arrays.toString(objs));

        //清空集合中所有的元素。
       // coll.clear();

        //判断当前集合是否为空。
        boolean b = coll.isEmpty(); //没有元素 true。有元素 false
        System.out.println(b);

        //获取集合的长度
        System.out.println(coll.size());

    }
}

第二章 Iterator迭代器(重点)

1.迭代器的作用

因为Collection集合没有提供根据索引查询的get()方法,所以我们要使用迭代器。

迭代器也支持泛型 Iterator ite = coll.iterator();

迭代器的作用:就是遍历集合数据。

迭代器适用于所有集合

2.获取迭代器

Collection集合有这个方法:

Collection coll = new ArrayList();
Iterator ite = coll.iterator();

3.迭代器常用方法

Iterator接口常用的方法:

方法说明
boolean hasNext()判断集合中有没有下一个元素
E next()获取集合中的元素
void remove()删除当前元素

在这里插入图片描述
示例代码:

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

public class TestIterator {
    public static void main(String[] args) {
        //创建Collection集合
        Collection<String> coll = new ArrayList<>();
        coll.add("宋吉吉");
        coll.add("王蓉");
        coll.add("马宝强");

        //通过Collection对象获取迭代器对象Iterator
        Iterator<String> ite = coll.iterator();
        while (ite.hasNext()){ //判断是否有下一个元素。 有 true 。 没有 false
            String s = ite.next();//获取下一个元素
            System.out.println(s);
        }

        /*if(ite.hasNext()){
            System.out.println(ite.next());
        }
        if(ite.hasNext()){
            System.out.println(ite.next());
        }
        if(ite.hasNext()){
            System.out.println(ite.next());
        }*/
    }
}

🎗经验分享:并发修改异常

  • 异常:

    • ConcurrentModificationException

      这个叫并发修改异常,在出现异常之后,可以不会读不回写,但是要知道这个是个什么异常。

  • 产生原因:

    • 在迭代器遍历集合的时候,如果使用集合对象给集合增加元素或删除元素,就会出现并发修改异常。

1.已知使用迭代器遍历集合的代码

public class Demo02Iterator {
    public static void main(String[] args) {
        //创建集合对象,往集合中添加元素
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        
        //使用迭代器遍历list集合
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
            
            /*
                需求: 增加一个判断,如果取出的元素s是"ccc"
                就给集合添加一个新的元素"itcast"
             */
            /*if("ccc".equals(s)){
                list.add("itcast");
            }*/
            
            /*
                需求: 增加一个判断,如果取出的元素s是"ccc"
                就把集合中的元素"ddd"删除
             */
            if("ccc".equals(s)){
                list.remove("ddd");
            }
        }
    }
}

2.出现的问题

在这里插入图片描述

3.问题的分析

在使用迭代器遍历集合的过程中,对集合的长度进行了修改,迭代器就会抛出并发修改异常

  • 添加元素
    在这里插入图片描述
  • 删除元素
    在这里插入图片描述

4.问题解决办法

第一种解决办法:

​在遍历集合的同时,不修改集合长度

public class Demo01Iterator {
    public static void main(String[] args) {
        //创建集合对象,往集合中添加元素
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        //使用迭代器遍历list集合
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
    }
}

运行结果:
在这里插入图片描述

第二种解决办法:

​ Iterator接口中有一个方法叫remove,作用也是删除集合中的元素

​ void remove() 删除使用next方法取出的集合中的元素

public class Demo01Iterator {
    public static void main(String[] args) {
        //创建集合对象,往集合中添加元素
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        //使用迭代器遍历list集合
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);

            /*
                需求: 增加一个判断,如果取出的元素s是"ccc"
                就把集合中的元素"ccc"删除
             */
            if("ccc".equals(s)){
                it.remove();//使用迭代器删除集合中元素的方法,删除it.next方法取出的元素
            }
        }
        System.out.println(list);
    }
}

运行结果:
在这里插入图片描述

5.增强for循环

  • 作用

    ​ 增强for循环是可以对集合或数组做遍历的。使用简单,所以比较常用。

  • 格式

for(数据类型 变量名 :数组或集合){
}

  • 增强for的本质

增强for循环的底层其实用到了迭代器,所以增强for循环也会出现并发修改异常。

在增强for里面也不能使用集合增加或删除元素

实际开发集合循环的使用方式:

import java.util.*;

public class TestListAndSet {
    public static void main(String[] args) {
        //测试List集合 (有序、可重复、有索引)
        List<String> list = new ArrayList();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");

        // System.out.println(list);
        /*for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            System.out.println(s);
        }*/

        //使用迭代器
        /*Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }*/

        //增强for
        /*for (String s : list) {
            System.out.println(s);
        }*/

        //测试Set集合 (无序、不可重复、没有索引)
        Set<String> set = new HashSet<>();
        set.add("aaa");
        set.add("bbb");
        set.add("ccc");
        set.add("ddd");

       // System.out.println(set);

        //迭代器
        /*Iterator<String> it = set.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }*/

        //增强for
        for (String s : set) {
            System.out.println(s);
        }
        
    }
}

第三章 泛型

1.泛型的作用

​ 泛型可以代表某种引用数据类型,在定义的时候如果不知道该定义什么类型,就可以定义成泛型。

​ 泛型用<>来定义,<>里面需要写一个大写字母来代表定义一个泛型。

​ 泛型作用:约束集合添加数据的类型。

2.类上定义泛型[了解]

类上定义泛型格式:

public class 类名<泛型类型>{
泛型类型 变量名;
}

  • 何时确定类型:

    在创建对象的时候确定具体的类型。
    
  • 代码演示:

/*
    如果一个类中需要一个不确定类型的变量,那么就适合使用泛型类。
    使用泛型类定义的变量,可以在类中任何位置使用。
 */
public class TestClass<T> {
    T t; //定义一个泛型类型的变量

    public void method(){
        System.out.println(t);
    }

}
package com.itheima.demo03fanxing;

public class Test01 {
    public static void main(String[] args) {
        TestClass<String> tc = new TestClass();
        tc.t = "aaa";

        tc.method();
    }
}

小节:定义泛型类可以使用类中的成员变量更灵活,而且在创建对象时还能约束类型。

3.方法上定义泛型[了解]

  • 方法上定义泛型格式:

public 泛型类型 void method(T t){
}

  • 何时确定类型:

    • 在调用方法的时候确定具体类型。
  • 代码演示:

/*
    演示泛型方法
 */
public class TestFanxingFF {

    public <T> void method(T t){
        System.out.println(t);
    }
}


//使用
package com.itheima.demo04fanxingff;

public class Test01 {
    public static void main(String[] args) {
        TestFanxingFF tf = new TestFanxingFF();

        tf.method("aaa");

    }
}

4.接口上定义泛型[了解]

  • 接口上定义泛型格式:

public class 接口名{
}

  • 何时确认类型:

    • 情况一:在实现类上确定具体类型
    • 情况二:在实现类上不确定具体类型,在创建对象时确定具体类型。
  • 代码演示:

//接口
public interface AAA<E> {
    //抽象方法
    void method(E e);
}

//情况一
//实现类
public class BBB implements AAA<String> {
    @Override
    public void method(String s) {

    }
}

//情况二
//实现类
//把接口上的泛型变成类上的泛型
public class CCC<E> implements AAA<E> {
    @Override
    public void method(E e) {
        
    }
}

public class Test03 {
    public static void main(String[] args) {
        //创建CCC的对象,确定具体类型
        CCC<String> c = new CCC<>();
        c.method("abc");
    }
}

5.泛型通配符

  • 格式:

    • 泛型通配符是在使用泛型而不是在定义泛型。
<?> : 可以匹配各种泛型类型[了解]
<? extends A> : 可以匹配A类型和A类型的子类类型 类型上限
<? super A> : 可以匹配A类型和A类型的父类类型 类型下限
import java.util.ArrayList;

/*
    泛型通配符
    <?>				: 可以匹配各种泛型类型[了解]
    <? extends A>	: 可以匹配A类型和A类型的子类类型  类型上限
    <? super  A>	: 可以匹配A类型和A类型的父类类型  类型下限
 */
public class TestFanxing {
    public static void main(String[] args) {
        ArrayList<Object> list0 = new ArrayList();
        ArrayList<Animal> list1 = new ArrayList();
        ArrayList<Cat> list2 = new ArrayList();

        method1(list0);
        method1(list1);
        method1(list2);

        //method2(list0); //报错
        method2(list1);
        method2(list2);


        method3(list0);
        method3(list1);
        // method3(list2); //报错


    }

    //<?>: 可以匹配各种泛型类型[了解]
    public static void method1(ArrayList<?> list){

    }

    //<? extends A>	: 可以匹配A类型和A类型的子类类型  类型上限
    public static void method2(ArrayList<? extends Animal> list){

    }

    //<? super  A>	: 可以匹配A类型和A类型的父类类型  类型下限
    public static void method3(ArrayList<? super Animal> list){

    }

}

第五章 List接口

1.List的特点

有序、可重复、有索引。

2.特有方法

方法说明
void add(int index, E element)在指定的索引添加元素
E get(int index)获取指定索引处的元素
E remove(int index)删除指定索引处的元素
E set(int index, E element)修改指定索引处的元素

代码演示:

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

/*
    void add(int index, E element)在指定的索引添加元素
    E get(int index)获取指定索引处的元素
    E remove(int index)删除指定索引处的元素
    E set(int index, E element)修改指定索引处的元素
 */
public class TestList {
    public static void main(String[] args) {
        //创建list集合
        List<String> list = new ArrayList();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");

        //void add(int index, E element)在指定的索引添加元素
        //list.add(2,"ee");

        //E get(int index)获取指定索引处的元素
        // String s = list.get(1);
        // System.out.println(s);

        //E remove(int index)删除指定索引处的元素
        // String s = list.remove(1); //返回值是删除的元素
        // System.out.println(s);

        // boolean b = list.remove("bb");
        // System.out.println(b);

        //E set(int index, E element)修改指定索引处的元素
        list.set(1, "gg");

        System.out.println(list);
    }
}

3.ArrayList集合

​ ArrayList底层用的是数组来存储数据。

​ 所以ArrayList集合特点增删元素慢,查询元素快。

4.LinkedList集合

​ LinkedList底层用的是双向链表来存储数据。

​ 所以LinkedList集合特点增删元素快,查询元素慢。

  • 两个集合效果演示
import java.util.ArrayList;
import java.util.LinkedList;

public class TestArrayListAndLinedList {
    public static void main(String[] args) {
        //测试ArrayList
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("宋喆");
        arrayList.add("马蓉");

        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            arrayList.add(1,"宝强");
        }
        long end = System.currentTimeMillis();

        System.out.println("ArrayList使用时间为:"+(end-start));


        //测试LinkedList
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("宋喆");
        linkedList.add("马蓉");
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            linkedList.add(1,"宝强");
        }
        long end1 = System.currentTimeMillis();

        System.out.println("LinkedList使用时间为:"+(end1-start1));
    }
}

ArrayList花费的时间8毫秒
LinkedList花费的时间2毫秒L
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值