Collection集合框架简介 与 泛型的基本概念

Collection集合框架


前言

包含(List接口:Vector集合、ArrayList集合、LinkedList集合)
特点

1、有序的集合,存取顺序一样
2、可以存储重复元素
3、有索引可以使用普通的for遍历

Set接口:TreeSet集合、HashSet集合(无序集合没有重复元素)、LinkedHashSet集合)
特点:

1、不允许重复元素
2、没有索引,不能使用普通的for循环来遍历

两个接口共性抽取形成父接口Collection(定义的是单列集合共性的方法,所有单列集合都可以使用的共性方法)
集合框架的学习:
1、学习顶层:顶层接口/抽象类中的共性方法所有 子类都可以使用
2、学习底层:底层不是接口就是抽象类,需要了解底层的子类创建对象使用

一、Collection接口常用方法

提供所有单列集合都可以使用的共性方法

public boolean add(E e)把给定的对象添加到集合

public void clear();清空集合中所有的元素

public boolean remove(E e);将给定的对象从集合当中删除,如果没有指定的元素会删除失败,返回false

public boolean contains(E e);判断当前集合中是否包含给定的对象

public boolean isEmpty(E e);判断集合是否为空

public int size();返回集合当中的元素个数

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

例如HashSet类 (无序且无重复元素)

public class Demo1Collection {
    public static void main(String[] args) {
        Collection<String> coll=new HashSet<>();
        //向无序无重复元素的HashSet集合当中添加元素
        coll.add("Arvin");
        coll.add("Kevin");
        coll.add("Kiki");
        System.out.println("集合当中的元素:"+coll);
        coll.remove("Kiki");
        System.out.println("通过remove删除指定元素Kiki后:"+coll);
        boolean a=coll.isEmpty();
        System.out.println("isEmpty判断集合是否为空"+a);
        System.out.println("通过size方法获取集合的元素个数:"+coll.size());
        System.out.println("通过contains方法判断集合当中是否有Kiki元素:"+coll.contains("Kiki"));

        coll.clear();
        System.out.println("通过clear方法清空集合元素后查询是狗为空:"+coll.isEmpty());
        Object[] array=coll.toArray();
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }

    }

运行结果:

集合当中的元素:[Kevin, Arvin, Kiki]
通过remove删除指定元素Kiki后:[Kevin, Arvin]
isEmpty判断集合是否为空false
通过size方法获取集合的元素个数:2
通过contains方法判断集合当中是否有Kiki元素:false
通过clear方法清空集合元素后查询是狗为空:true

二、Iterator接口

迭代:即对Collection集合当中通用的取出元素的方式
两个常用的方法:

public boolean hasNext();如果任然有元素可以迭代,则返回true
判断集合有没有下一个元素,有就返回true,没有返回false

E next();返回迭代的下一个元素

Iterator是一个接口,无法直接使用,需要实现类的对象,获取的方法比较特殊
Collection接口当中有一个方法,叫做iterator(),这个方法可以返回实现类的对象

迭代器的使用步骤:(重点)
1、使用集合Collection调用方法iterator()获取迭代器的实现类对象

	Collection coll=new HashSet<Integer>();
	Iterator iterator = coll.iterator();

2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
3、使用Iterator接口 的方法next取出集合中的下一个元素

注意:Iterator接口也是有泛型的,迭代的泛型跟着集合走,泛型跟集合保持一致

public class Demo2Iterator {
    public void method(Iterator<String> e){
        while(true){
            if(e.hasNext()){
                System.out.println(e.next());
            }
            else{break;}
        }
    }
    public static void main(String[] args) {
        //多态
        Collection<String> coll=new ArrayList<>();
        coll.add("Arvin");
        coll.add("Kevin");
        coll.add("Kiki");
        //用个Collection的方法iterator()获取Iterator迭代器接口的对象
        Iterator<String> it=coll.iterator();
        new Demo2Iterator().method(it);
      
    }
}

结果:

Arvin
Kevin
Kiki

迭代器的原理:

	Collectoin<E> coll=new HashSet<E>();
	Iterator<E> it=coll.iterator();
	
	coll.itetator();将集合的索引从0指向-1
	
	it.hasNext();判断集合有没有下一个元素,有就返回true,没有返回false
	
	it.next();做了两件事:
	1、打印集合的下一个元素
	2、把指针向后移动一位

增强for循环:(底层使用的也是迭代器,只是使用for循环的格式简化了迭代器的书写)
是jdk1.5之后出现的新特性。
Collection extends Iterable;所有的单列表集合都可以使用增强for循环。
public interface Iterable;实现这个接口允许对象成为foreach语句的目标。
所有增强for循环可以遍历数组和集合。

格式:
for(集合/数组数据类型 变量名:集合/数组名){
sout(变量名)}

public class Demo3Foreach {
    public static void main(String[] args) {
        //创建以个数组
        String[] array={"Arvin","Kevin","Kiki"};
        //使用增强for循环来遍历这个数组
        for (String i:array
             ) {
            System.out.println("增强for循环遍历数组:"+i);
        }
        //创建一个集合
        HashSet<String> set=new HashSet<>();
        set.add("Arvin");
        set.add("Kevin");
        set.add("Kiki");
        //foreach遍历;;注意第一个是数组或者集合的数据类型
        for (String i:set
             ) {
            System.out.println("foreach来遍历集合:"+i);
        }
    }
}
DataResult:
增强for循环遍历数组:Arvin
增强for循环遍历数组:Kevin
增强for循环遍历数组:Kiki
foreach来遍历集合:Kevin
foreach来遍历集合:Arvin
foreach来遍历集合:Kiki

泛型的概念

是一种未知的数据类型,当我们不知到使用什么数据类型的时候,可以使用泛型 泛型也可以看作与i个变量用来接受数据类型。

E e:Element 元素
T t:Type 类型

列如:ArrayList集合再定义的时候,不知道集合当中都会存储什么类型的数据,所以使用泛型
所以E:看作未知数据类型
再创建对象的时候,就会确定泛型的数据类型
列如 ArrayList list=new ArrayList<>();
会把数据类型作为参数传递,把数据类型的值给泛型E

使用泛型的好处:

1、不使用泛型:好处 集合不使用泛型,默认的类型就是Object类型,可以存储任意类型的数据
弊端:不安全,会发生异常
默认的Object类型如果打印的结果想要转型成string字符串,那么
需要使用向下转型,先将类型转换成String类型,但是如果字符串里面有Integer等类型的数据,那么就会产生类型转换错误。

2、使用泛型:
2.1、避免了类型转换的麻烦,存储的什么类型,取出的就是什么类型
2.1、把运行期的异常(代码运行之后才会产生的异常),提升到了编译器(写代码的时期)
弊端:
泛型是什么类型,就只能存储什么类型的数据

public class Demo4KownElement {
    public static void main(String[] args) {
        //不使用泛型创建一个集合,默认是Object类型,可以存储任意数据
        HashSet set=new HashSet<>();
        set.add("aaa");
        set.add(3);
        set.add(6);
        //获取迭代器对像来输出遍历输出
        Iterator it=set.iterator();
        /*while(it.hasNext()){
            //现在想用int来接受这些参数
            //int num=(Integer)it.next();//ClassCastException程序运行报错ClassCastException
            //发生类类型转换异常,应为集合当中有字符串
            //System.out.println(num);
        }*/
        //使用泛型来创建一个集合
        ArrayList<Character> list=new ArrayList<>();
        list.add('a');
        list.add('b');
        //Object a=list.get(0);
        //除了Object只能当前泛型的数据类型才能接收数据
        char a=list.get(0);

    }
}

定义和使用含有泛型的类

就可以在类创建对象的时候进行定义数据类型

public class Demo5Calss_E<E> {
    private E name;
    private E sex;

    public Demo5Calss_E() {
    }

    public E getName() {
        return name;
    }

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

    public E getSex() {
        return sex;
    }

    public void setSex(E sex) {
        this.sex = sex;
    }

    public static void main(String[] args) {
        //定义一个泛型的类,在创建对象的时候定义类型,类中所有的东西都是E  泛型
        Demo5Calss_E<String> e=new Demo5Calss_E<>();
     e.setName("Arvin");
        e.setSex("男");
        String a = e.getName();
        String b = e.getSex();
        System.out.println("姓名"+a+"  "+"年龄"+b);
    }
}
DataResult:
姓名Arvin  年龄男

定义含有泛型的方法

泛型定义在方法修饰符和返回值之间

格式:修饰符 《泛型》 返回值类型方法名 (参数列表(泛型)){}
含有泛型的方法,在调用方法的时候就确定泛型的数据类型,传递什么类型的参数、泛型就是什么类型

定义含有泛型的方法:泛型定义在方法修饰符和返回值之间
  格式:修饰符 《泛型》 返回值类型方法名 (参数列表(泛型)){}
  含有泛型的方法,在调用方法的时候就确定泛型的数据类型,传递什么类型的参数、
  泛型就是什么类型
  public class Demo6Method_E {
    //创建一个含有泛型的成员方法
    public <E> void method(E e){
        E name=e;
        System.out.println(name);
    }
    //创建一个含有泛型的静态方法
    public static <E> void method2(E e){
        System.out.println(e);
    }
    public static void main(String[] args) {
        //创建当前类的对象
        Demo6Method_E demo6=new Demo6Method_E();
        //通过对象调用含有泛型的方法,传递的参数是什么数据类型,泛型就是什么类型
        demo6.method("Arvin");
        demo6.method(66);
        //调用静态方法有两种方式1、通过对象调用(不推荐)2、之间使用类名来调用
        demo6.method2("Arvin");
        Demo6Method_E.method2("Kevin");

    }
}
DataResult:
Arvin
66
Arvin
Kevin

定义接口当中的泛型

1、定义接口的实现类,实现接口,指定接口的泛型
public class Impl implements Interface<指定泛型>{}

public class Demo7Implements implements Demo7Interface_E<String> {
    //数据类型定义在接口后边
    //重写覆盖方法
    @Override
    public void method1(String e){
        System.out.println(e);
    }

    public static void main(String[] args) {
        Demo7Implements impl=new Demo7Implements();
        impl.method1("Arvin");
        //impl.method1(44);

    }
}
DataResult:
Arvin

接口使用什么泛型,实现类就使用什么泛型,相当于实现类是一个含有泛型的类,在创建对象的时候确定泛型的数据类型

public class Implements<E> implements Interface<E> {}

public class Demo7Implements_2<E> implements Demo7Interface_E<E>{
    //接口的泛型和实现类的泛型一样
    @Override
    public void method1(E o) {
        System.out.println(o);
    }

    public static void main(String[] args) {
        //通过创建实现类的对象给泛型数据类型
        Demo7Implements_2<String> impl=new Demo7Implements_2<>();
        impl.method1("Arvin");
    }
}
DataResult:
Arvin

泛型的通配符<?>

? :代表任意的数据
使用方式:
不能创建对象,只能作为方法的参数使用

作用:列如可以定义一个方法,可以遍历所有类型的ArrayList集合
对于写ArrayList 是不可以的应为泛型没有继承概念
public void printArrays(ArrayList<?> lsit){

		}
public class Demo8ElemntType {
    public static void method(ArrayList<?> list){
        //通过Collection的对象来调用iterator()方法,获取迭代器的对象
        Iterator<?> it=list.iterator();
        //用迭代器来遍历集合
        while (it.hasNext()){
            System.out.println(it.next());
        }
    }
    public static void main(String[] args) {
        //创建了连个不同数据类型的集合
        ArrayList<String> list=new ArrayList<>();
        list.add("Arvin");
        ArrayList<Integer> list2=new ArrayList<>();
        list2.add(66);
        //现在定义一个方法可以接受任意数据类型,来遍历集合
        //就需要使用泛型通配符?
        method(list);
        method(list2);

    }
}
DataResult:
Arvin
66

泛型的上下限

泛型的上限: <? extends 数据类型> 代表使用的泛型只能是数据类型的子类/本身
泛型的下限:<? super 数据类型> 代表使用的泛型必须是数据类型是父类或者本身
对于泛型通配符权限的一个限定

相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页