目录

1.数组和集合的区别

集合体系

Collection集合概述

 Collection集合特有遍历方式:迭代器Iterator

迭代器中删除的方法

 增强for

 List集合

List集合的特有方法

 数据结构

栈和队列

数组和链表

List集合的实现类

 LinkedList集合

泛型 

自定义泛型类:【这个类可以创建各种数据类型的对象】

泛型方法 

 泛型接口

类型通配符 

类型通配符【泛型的上限下限】


1.数组和集合的区别

+ 相同点

  都是容器,可以存储多个数据

+ 不同点

  + 数组的长度是不可变的,集合的长度是可变的

  + 数组可以存基本数据类型和引用数据类型

    集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类


集合体系

java list 最大可以保存多少条数据 list最大可以装多少条_System

java list 最大可以保存多少条数据 list最大可以装多少条_System_02

List集合:有存储顺序,允许重复元素,有索引

Set集合:不允许重复,没有索引【不能使用普通for】


Collection集合概述

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

方法名

说明

boolean add(E e)

添加元素

boolean remove(Object o)

从集合中移除指定的元素

boolean removeIf(Object o)

根据条件进行移除

boolean remove(E e)

把给定的对象在当前集合中删除

void clear()

清空集合中的元素

boolean contains(Object o)

判断集合中是否存在指定的元素

boolean isEmpty()

判断集合是否为空

int size()

集合的长度,也就是集合中元素的个数

public Object[] toArray()

把集合中的元素,存储到数组中。

public class Demo01Collection {
    public static void main(String[] args) {
        //创建集合对象,可以使用多态
        //Collection<String> coll = new ArrayList<>();
        Collection<String> coll = new HashSet<>();//无序的,不允许存储重复元素
        System.out.println(coll);//重写了toString方法  []
        System.out.println(new ArrayList<String>());//【】


        /*
            public boolean add(E e):  把给定的对象添加到当前集合中 。
            返回值是一个boolean值,一般都返回true,所以可以不用接收
         */
        boolean b1 = coll.add("张三");
        System.out.println("b1:"+b1);//b1:true
        System.out.println(coll);//[张三]
        coll.add("李四");
        coll.add("李四");
        coll.add("赵六");
        coll.add("田七");
        System.out.println(coll);//[张三, 李四, 赵六, 田七]



        /*
            public boolean remove(E e): 把给定的对象在当前集合中删除。
            返回值是一个boolean值,集合中存在元素,删除元素,返回true
                                集合中不存在元素,删除失败,返回false
         */
        boolean b2 = coll.remove("赵六");
        System.out.println("b2:"+b2);//b2:true

        boolean b3 = coll.remove("赵四");
        System.out.println("b3:"+b3);//b3:false
        System.out.println(coll);//[张三, 李四, 田七]



        /*
            public boolean contains(E e): 判断当前集合中是否包含给定的对象。
            包含返回true
            不包含返回false
         */
        boolean b4 = coll.contains("李四");
        System.out.println("b4:"+b4);//b4:true

        boolean b5 = coll.contains("赵四");
        System.out.println("b5:"+b5);//b5:false



        //public boolean isEmpty(): 判断当前集合是否为空。 集合为空返回true,集合不为空返回false

        boolean b6 = coll.isEmpty();
        System.out.println("b6:"+b6);//b6:false



        //public int size(): 返回集合中元素的个数。

        int size = coll.size();
        System.out.println("size:"+size);//size:3



        //public Object[] toArray(): 把集合中的元素,存储到数组中。


        Object[] arr = coll.toArray();
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        for (Object o : arr) {
            System.out.println(o);
        }
        //public void clear() :清空集合中所有的元素。但是不删除集合,集合还存在
        coll.clear();
        System.out.println(coll);//[]
        System.out.println(coll.isEmpty());//true
    }
}

 Collection集合特有遍历方式:迭代器Iterator

  • 迭代器介绍
  •  Iterator<E>     iterator(): 返回此集合的迭代器对象,该迭代器对象默认指向当前集合得0索引 
  •  Iterator中的常用方法
    boolean hasNext(): 判断当前位置是否有元素可以被取出
  • E next(): 获取当前位置的元素,将迭代器对象移向下一个索引位置
  • void remove(): 删除迭代器对象当前指向的元素【此remove是迭代器的remove≠集合的remove】
  • 迭代器的泛型要与集合的泛型保持一致
public class Demo01Iterator {
    public static void main(String[] args) {
        //创建一个集合对象
        Collection<String> coll = new ArrayList<>();
        //往集合中添加元素
        coll.add("姚明");
        coll.add("科比");
        coll.add("麦迪");
        coll.add("詹姆斯");
        coll.add("艾弗森");

        /*
            1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
            注意:
                Iterator<E>接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型
         */
        //多态  接口            实现类对象
        Iterator<String> it = coll.iterator();


        /*
            发现使用迭代器取出集合中元素的代码,是一个重复的过程
            所以我们可以使用循环优化
            不知道集合中有多少元素,使用while循环
            循环结束的条件,hasNext方法返回false
         */
        while(it.hasNext()){//需要使用多态写法,子类没有hasnext等方法,需要想上找到接口中的方法
            //不可以用coll.iterator()
            String e = it.next();
            System.out.println(e);
        }
        System.out.println("----------------------");
        for(Iterator<String> it2 = coll.iterator();it2.hasNext();){
            String e = it2.next();
            System.out.println(e);
        }
}
}

迭代器中删除的方法

void remove(): 删除迭代器对象当前指向的元素

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--;        【原因:arraylist是一个动态集合,比如一个集合有五个元素,0-4个索引,当删除2号索引后,集合长度减为4,原本2号索引的位置被3号索引所替代,指针开始从“3”号索引开始继续往下,直接跳过了此元素的判断,所以需要i值减一位,从而达到判断3号索引】
            }
        }
*/

//优化
 Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String s = it.next();
            if("b".equals(s)){
                //指向谁,那么此时就删除谁.
                it.remove();            【迭代器里的remove解决了此问题】
            }
        }

        System.out.println(list);
    }
}

 增强for

其内部原理是一个迭代器,只有实现Iterable接口的类才可以使用迭代器和增强for。

Collection继承了此接口可以使用,Map没有实现此接口,不能使用

格式

for(集合/数组中元素的数据类型 变量名 : 集合/数组名) {

// 已经将当前遍历到的元素封装到变量中了,直接使用变量即可

}

 三种循环的使用场景
如果需要操作索引,使用普通for循环
如果在遍历的过程中需要删除元素,请使用迭代器

如果仅仅想遍历,那么使用增强for

 List集合

List集合的特点

  • 存取有序
  • 可以重复
  • 有索引【可以通过索引进行一系列操作】

List集合的特有方法

方法名

描述

void add(int index,E element)

在此集合中的指定位置插入指定的元素,原来该索引处元素后移

E remove(int index)

删除指定索引处的元素,返回被删除的元素

E set(int index,E element)

修改指定索引处的元素,返回被修改的元素

E get(int index)

返回指定索引处的元素

 数据结构

栈和队列

java list 最大可以保存多少条数据 list最大可以装多少条_泛型_03

队列

java list 最大可以保存多少条数据 list最大可以装多少条_java_04

数组和链表

数据结构之数组

java list 最大可以保存多少条数据 list最大可以装多少条_迭代器_05

链表

链表中的每个元素叫结点,结点是一个独立的对象

java list 最大可以保存多少条数据 list最大可以装多少条_迭代器_06

java list 最大可以保存多少条数据 list最大可以装多少条_迭代器_07

java list 最大可以保存多少条数据 list最大可以装多少条_泛型_08

java list 最大可以保存多少条数据 list最大可以装多少条_java_09

链表是一个增删快的模型(对比数组) 

java list 最大可以保存多少条数据 list最大可以装多少条_System_10

java list 最大可以保存多少条数据 list最大可以装多少条_System_11

双向链表:先判断元素离哪一头近,离后头近,则从后往前查找,反之。 

List集合的实现类

 List集合子类的特点

  • ArrayList集合
    底层是数组结构实现,查询快、增删慢
  • LinkedList集合
    底层是链表结构实现,查询慢、增删快

 LinkedList集合

特有方法,不能多态创建集合

LinkedList<String> list=new LinkedList<>();

方法名

说明

public void addFirst(E e)

在该列表开头插入指定的元素

public void addLast(E e)

将指定的元素追加到此列表的末尾

public E getFirst()

返回此列表中的第一个元素

public E getLast()

返回此列表中的最后一个元素

public E removeFirst()

从此列表中删除并返回第一个元素

public E removeLast()

从此列表中删除并返回最后一个元素

泛型 

/**
 *  不写泛型的弊端
 */
public class GenericitySummarize {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();        
        list.add("aaa");
        list.add("bbb");                            
        list.add("ccc");
        list.add(123);

        Iterator it = list.iterator();
        while(it.hasNext()){
 【假如不写上泛型】           
(1)默认为object类型即object obj=“aaa”;,而obj中没有length方法,程序运行就会报错。只有通过
强转将obj转为string类,才能调用String特有的length方法。
(2)如果没写泛型,假如add添加一个integer类型数据,那么下面语句中会把integer类数据强转为
String类,而两个类型间无法强转,运行时就会报错,类型不匹配
            String next = (String) it.next();
            int len = next.length();
            System.out.println(len);

        }
    }
}

泛型的好处

  1. 把运行时期的问题提前到了编译期间【确定了泛型就可以把错误判断提前到编译期,如果泛型不对会标红处理,提前预知错误】
  2. 避免了强制类型转换【如果没有泛型,那么add添加的数据默认为object类型,如果想使用比如String泛型的特定方法。length,无法使用,需要先把object类型数据强转为String类型,如果又添加add一个int类型数据,在进行强转就会报错】

 泛型的定义格式:

  • <类型>: 指定一种类型的格式.尖括号里面可以任意书写,一般只写一个字母.例如: <E> <T>
  • <类型1,类型2…>: 指定多种类型的格式,多种类型之间用逗号隔开.例如: <E,T> <K,V>

可以使用的地方:

类后面                   → 泛型类

方法申明上            →泛型方法

接口后面                →泛型接口


泛型类的总结
如果一个类的后面有<E>,表示这个类是一个泛型类。
创建泛型类的对象时,必须要给这个泛型确定具体的数据类型。

public class ArrayList<E>【此类后面<E>表泛型】 extends AbstractList<E>  【Arraylist类】
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{                
XXX                }

【创建集合对象时,就在类这里指定了泛型类型】
ArrayList<String> list=new ArrayList<>();

自定义泛型类:【这个类可以创建各种数据类型的对象】

  • 定义格式

修饰符 class 类名<类型> { }

泛型是一个未知的数据类型,当我们不确定什么什么数据类型的时候,可以使用泛型泛型可以接收任意的数据类型,可以使用Integer,String,Student... 创建对象的时候确定泛型的数据类型

在主函数中创建对象时,指定自己想要的泛型类

text<String> tx=new text<>("asdf");

text<Integer> tx=new text<>(123);

示例:

【泛型类】
public class Generic<T> {
    private T t;

    public T getT() {        Alt+insert自动生成get,set
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}
【测试类】
public class GenericDemo1 {
    public static void main(String[] args) {
        Generic<String> g1 = new Generic<String>();
        g1.setT("杨幂");
        System.out.println(g1.getT());

        Generic<Integer> g2 = new Generic<Integer>();
        g2.setT(30);
        System.out.println(g2.getT());

        Generic<Boolean> g3 = new Generic<Boolean>();
        g3.setT(true);
        System.out.println(g3.getT());
    }
}

泛型方法 【在调用方法的时候确定泛型的数据类型】

  • 定义格式

修饰符 <泛型类型> 返回值类型 方法名(泛型类型 变量名) { } 【修饰符后的<类型>表创建的是一个泛型方法】

含有泛型的方法,在调用方法的时候确定泛型的数据类型传递什么类型的参数,泛型就是什么类型

  • 示例代码
【带泛型方法的类】
public class Generic {
    public <T> void show(T t) {
        System.out.println(t);
    }
}


【测试类】
public class GenericDemo2 {
    public static void main(String[] args) {
	    Generic g = new Generic();
        g.show("柳岩");
        g.show(30);
        g.show(true);
        g.show(12.34);
    }
}

 泛型接口

定义格式

修饰符 interface 接口名<泛型类型> { }

eg:

public interface GenericInterface<I> { public abstract void method(I i); //虽然是一个泛型方法,但在接口处就已经声明了这是一个泛型//所以在修饰符处不用在写<I>了 }

泛型接口的使用方式:

        实现类也不给泛型【在创建实现类对象的时候指定泛型】

java list 最大可以保存多少条数据 list最大可以装多少条_迭代器_12


        实现类确定具体的数据类型 

java list 最大可以保存多少条数据 list最大可以装多少条_泛型_13

  • 示例代码
【泛型接口】
public interface Generic<T> {
    void show(T t);
}

【泛型接口实现类1】
	定义实现类时,定义和接口相同泛型,创建实现类对象时明确泛型的具体类型
public class GenericImpl1<T> implements Generic<T> {
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}

【泛型接口实现类1】
	定义实现类时,直接明确泛型的具体类型
public class GenericImpl2 implements Generic<Integer>{
     @Override
     public void show(Integer t) {
          System.out.println(t);
     }
}

【测试类】
public class GenericDemo3 {
    public static void main(String[] args) {
        GenericImpl1<String> g1 = new GenericImpl<String>();
        g1.show("林青霞");
        GenericImpl1<Integer> g2 = new GenericImpl<Integer>();
        g2.show(30);
      
        GenericImpl2 g3 = new GenericImpl2();
      	g3.show(10);
    }
}

类型通配符 

类型通配符

  • 类型通配符: <?>
  • ArrayList<?>: 表示元素类型未知的ArrayList,它的元素可以匹配任何的类型
  • 但是并不能把元素添加到ArrayList中了,获取出来的也是父类类型
public static void main(String[] args) {
        ArrayList<Integer> list01 = new ArrayList<>();
        list01.add(1);
        list01.add(2);

        ArrayList<String> list02 = new ArrayList<>();
        list02.add("a");
        list02.add("b");

        printArray(list01);
        printArray(list02);

        //ArrayList<?> list03 = new ArrayList<?>();
    }

    /*
        定义一个方法,能遍历所有类型的ArrayList集合
        这时候我们不知道ArrayList集合使用什么数据类型,可以泛型的通配符?来接收数据类型
        注意:
            泛型没有继承概念的
     */
    public static void printArray(ArrayList<?> list){
        //使用迭代器遍历集合
        Iterator<?> it = list.iterator();
        while(it.hasNext()){
            //it.next()方法,取出的元素是Object,可以接收任意的数据类型
            Object o = it.next();
            System.out.println(o);
        }
    }
}
  • 类型通配符上限: <? extends 类型>
  • ArrayListList <? extends Number>: 它表示的类型是Number或者其子类型
  • 类型通配符下限: <? super 类型>
  • ArrayListList <? super Number>: 它表示的类型是Number或者其父类型
  • 泛型通配符的使用
public class GenericDemo4 {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        ArrayList<Number> list3 = new ArrayList<>();
        ArrayList<Object> list4 = new ArrayList<>();

        method(list1);
        method(list2);
        method(list3);
        method(list4);

        getElement1(list1);
        getElement1(list2);//报错
        getElement1(list3);
        getElement1(list4);//报错

        getElement2(list1);//报错
        getElement2(list2);//报错
        getElement2(list3);
        getElement2(list4);
    }
  
    // 泛型通配符: 此时的泛型?,可以是任意类型
    public static void method(ArrayList<?> list){}
    // 泛型的上限: 此时的泛型?,必须是Number类型或者Number类型的子类
    public static void getElement1(ArrayList<? extends Number> list){}
    // 泛型的下限: 此时的泛型?,必须是Number类型或者Number类型的父类
    public static void getElement2(ArrayList<? super Number> list){}

}