集合体系,Collection,List,LinkedList,泛型

目录

1.数组和集合的区别

集合体系​

Collection集合概述

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

迭代器中删除的方法

 增强for

 List集合

List集合的特有方法

 数据结构

栈和队列

数组和链表

List集合的实现类

 LinkedList集合

泛型 

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

泛型方法 

 泛型接口

类型通配符 

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


1.数组和集合的区别

+ 相同点

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

+ 不同点

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

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

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


集合体系

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迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊 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)返回指定索引处的元素

 数据结构

栈和队列

队列

数组和链表

数据结构之数组

链表

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

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

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

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>了

}

泛型接口的使用方式:
        实现类也不给泛型【在创建实现类对象的时候指定泛型】
        实现类确定具体的数据类型

 

  • 示例代码

【泛型接口】
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){}
    
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值