Collection集合、迭代器、泛型(超详细)

 本文主要介绍Collection集合、迭代器、泛型的定义以及详细的使用方法。

目录

Collection集合

1.集合定义

2.集合和数组的区别

3.Collection集合常用功能

Iterator迭代器

1.Iterator接口

2.增强for循环

泛型

1.概念

2.为什么要用泛型

3.定义与使用

总结


Collection集合

1.集合定义

      集合是Java中提供一种容器,可以用来存储不同类型的数据对象。

2.集合和数组的区别

     a. 数组的长度是固定的,定义后就不能改变。集合的长度是可变的。

     b. 数组中存储的是同意类型的元素,只能存储基本数据类型值。集合存储的都是对象,而且对象的类型可以不一致。

在开发中一般当对下岗多的时候,使用集合进行存储。

3.Collection集合常用功能

定义:Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。

实例:()

package demo1_Collection;

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

/*
    java.util.Collection接口:
        所有单列集合的最顶层的接口,里面定义了所有单列集合共性的方法
        任意的单列集合都可以使用Collection接口中的方法

    共性方法:
        - public boolean add(E e):  把给定的对象添加到当前集合中 。
        - public void clear() :清空集合中所有的元素。
        - public boolean remove(E e): 把给定的对象在当前集合中删除。
        - public boolean contains(E e): 判断当前集合中是否包含给定的对象。
        - public boolean isEmpty(): 判断当前集合是否为空。
        - public int size(): 返回集合中元素的个数。
        - public Object[] toArray(): 把集合中的元素,存储到数组中。
 */
public class Test01_Collection {
    public static void main(String[] args) {
//        Collection<String> collection= demo1_Add();
//        demo2_Remove();
//        demo3_Clear();
//        demo4_Contains();
//        demo5_IsEmpty();
//        demo6_Size();
        demo7_ToArray();
    }

    public static void demo7_ToArray(){
        Collection<String> collection= demo1_Add();
        // Object[] toArray()转换成一个Object数组
        Object[] arr=collection.toArray();
        //遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

    public static void demo6_Size(){
        Collection<String> collection= demo1_Add();
        int size=collection.size();
        System.out.println(size);   //  3
    }

    public static void demo5_IsEmpty(){
        Collection<String> collection= demo1_Add();
        boolean b1=collection.isEmpty();

        collection.clear();
        boolean b2=collection.isEmpty();
        System.out.println(b1+"==="+b2);        //false===true
    }

    public static void demo4_Contains(){
        Collection<String> collection= demo1_Add();

        boolean b1=collection.contains("小太阳");
        boolean b2=collection.contains("小兔崽子");
        System.out.println(b1+"==="+b2);        //true===false
    }

    public static void demo3_Clear(){
        Collection<String> collection=demo1_Add();
        System.out.println(collection);         //[小太阳, 小月亮, 小星星]
        collection.clear();
        System.out.println(collection);         //[]

    }


    public static Collection<String> demo1_Add() {
        /*
             - public boolean add(E e):  把给定的对象添加到当前集合中 。
             返回值为Boolean值,一般为true,所有不用接收
         */
        //创建集合对象,可以使用多态
        Collection<String> collection = new ArrayList<>();

        boolean b = collection.add("小太阳");
        collection.add("小月亮");
        collection.add("小星星");
        return collection;
    }

    public static void demo2_Remove() {
        /*
              - public boolean remove(E e): 把给定的对象在当前集合中删除。
              存在元素,删除元素,返回true
              不存在删除元素,返回false
         */
        //创建集合对象,可以使用多态
        Collection<String> collection =demo1_Add();

        boolean b1 = collection.remove("小星星");
        boolean b2 = collection.remove("小兔崽子");
        System.out.println(b1 + " " + b2);  //true  false
        System.out.println(collection);
    }
}

Iterator迭代器

1.Iterator接口

Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。

迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

Iterator接口常用方法:

- public E next():返回迭代的下一个元素。
- public boolean hasNext():如果仍有元素可以迭代,则返回 true。

 迭代器使用步骤:

          a.获取迭代器的实现类对象,用Iterator接口接收

          b.使用Iterator接口中hasNext方法判断还有没有下一个元素

          c.使用Iterator接口的方法next()取出集合的下一个元素

实例:

package demo2_Iterator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
    java.util.Iterator接口:迭代器(对单列集合进行遍历)
    常用方法:
        - public boolean hasNext()  如果仍有元素可以迭代,则返回true。
                判断集合中还有没有下一个元素,有则返回true,否则返回false
        - public E next()   返回迭代的下一个元素,就是取出集合中的下一个元素
    Iterator迭代器是一个接口,需要使用Iterator接口的实现类对象。
        - public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。

    迭代器的使用步骤:
        1.获取迭代器的实现类对象,使用Iterator接口接收
        2.使用Iterator接口中的方法hasNext判断还有没有下一个元素
        3.使用Iterator接口的方法next取出集合中的下一个元素
 */
public class Test01_Iterator {
    public static void main(String[] args) {
        //创建对象
        Collection<String> collection=new ArrayList<>();
        //添加元素
        collection.add("小太阳");
        collection.add("小月亮");
        collection.add("小星星");

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

        //泛型指的是 迭代出元素的数据类型
        while(it.hasNext()){        //2.判断释放有迭代元素
            String str=it.next();   //3.获取迭代出的元素
            System.out.println(str);
        }
    }
}

2.增强for循环

       增强for循环(也称for  each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是Iterator迭代器,所以遍历的过程中,不能对集合中的元素进行增删操作(否则会报错)。

格式:

for(集合/数组的数据类型  变量名 : 集合名/数组名){
    System.out.println(变量名);
}

 实例:(它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作 !!!)

重要的事情说两遍!!!

package demo2_Iterator;

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

//增强for循环实例
public class Test02_For {
    public static void main(String[] args) {
        //创建集合对象
        Collection<String> collection=new ArrayList<>();
        collection.add("会发光啊");
        collection.add("小太阳");
        collection.add("小月亮");

        //使用增强for循环打印
        for(String str : collection){
            System.out.print(str+"   ");    //会发光啊   小太阳   小月亮   
        }
    }
}

泛型

1.概念

       泛型:是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型

       泛型也可以看作是一个变量,用来接收数据类型

                E  e: Element  元素

                T   t: Type 类型

定义集合的时候经常用到泛型,例如ArrayList<String> str=new ArrayList<>(),这里String就可以理解为泛型。

2.为什么要用泛型

       在前面学习集合的时候,我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object对象。当我们取出每一个对象,并且进行相应的操作,这时候必须采用类型转换。

举例如下:

package demo3_Generic;

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

//为什么使用泛型
public class Test03_Generic {
    public static void main(String[] args) {
        //创建集合对象
        Collection collection=new ArrayList();
        //集合没有做限定,默认存储Object对象
        collection.add("小太阳");
        collection.add(520);
        collection.add("会发光啊");

        Iterator iterator=collection.iterator();
        while (iterator.hasNext()){
            //需要打印每个元素的长度,就要把迭代出的每个对象转成Strinl类型
            String str=(String )iterator.next();
            System.out.print(str+"  ");
        }
    }
}

 结果报错:(java.lang.ClassCastException)--类型转换异常

小太阳  Exception in thread "main" java.lang.ClassCastException: java.base/java.lang.Integer cannot be cast to java.base/java.lang.String
	at demo3_Generic.Test03_Generic.main(Test03_Generic.java:20)

Process finished with exit code 1

 为什么会发生类型转换异常呢?

          由于集合中什么类型的元素都可以存储。导致取出时强转引发运行时 ClassCastException。

解决方案:

          Collection虽然可以存储各种对象,但实际上通常Collection只存储同一类型对象。例如都是存储字符串对象。因此在JDK5之后,新增了泛型(Generic)语法,让你在设计API时可以指定类或方法支持泛型,这样我们使用API的时候也变得更为简洁,并得到了编译时期的语法检查。

3.定义与使用

     A.  含有泛型的类:创建对象的时候确定泛型的数据类型

        实例:

创建含有方法的类

package demo3_Generic;
/*
    定义一个含有泛型的类,模拟ArrayList集合
    泛型是一种未知的数据类型,当我们不确定用什么数据类型的时候,可以使用泛型
    泛型可以接收任意的数据类型
    创建对象的时候确定泛型的数据类型
 */
public class Test01_StudentGeneric<E> {
    private E name;
    public E getName(){
        return name;
    }

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

 创建类对象并确定泛型的数据类型,调用类方法:

package demo3_Generic;

public class Student_Test {
    public static void main(String[] args) {
        //创建对象的时候确定泛型的数据类型,不写泛型默认为Object类型
        Test01_StudentGeneric sc=new Test01_StudentGeneric();
        sc.setName("没有写泛型默认Object类型");
        Object obj=sc.getName();
        System.out.println(obj);      //  没有写泛型默认Object类型

        //创建对象,泛型使用String类型
        Test01_StudentGeneric<String> stu=new Test01_StudentGeneric<>();
        stu.setName("小太阳啊");
        System.out.println(stu.getName());     //小太阳啊
    }
}

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

         实例:

package demo3_Generic;
/*
    定义含有泛型的方法: 泛型定义在方法的修饰符和返回值之间
    格式:
        修饰符 <泛型>  返回值类型 方法名(使用泛型){
            方法体
        }

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

    //定义一个含有泛型的方法
    public <T> void method1(T t){
        System.out.println(t);
    }

    //定义一个含有泛型的静态方法
    public static  <T> void  method2(T t){
        System.out.println(t);
    }
}

调用方法:可以传递任意类型的参数。

package demo3_Generic;
//测试含有泛型的方法
public class Person_Test {
    public static void main(String[] args) {
        //创建对象
        Test02_PersonGeneric per=new Test02_PersonGeneric();

        /*
            调用含有泛型的方法
            传递什么类型的参数,泛型就是什么类型
         */
        per.method1("小太阳");             //小太阳
        per.method1(123);                   //123

        //调用含有泛型的静态方法
        Test02_PersonGeneric.method2("会发光啊");   //会发光啊
    }
}

        C.定义含有泛型的接口 

  第一种使用方式:定义接口的实现类,实现接口,在实现类中指定接口的泛型。

  第二种使用方式:创建对象的时候确定泛型的类型。接口使用什么泛型,实现类就使用什么泛型,类跟着接口走,就相当于定义 了一个含有泛型的类。

实例: 第一种:

定义接口和实现类:(为了省略篇幅,把接口和实现类放一块了,阅读博客时建议自己手动打一边,切勿直接复制粘贴。。。)

//接口
package demo3_Generic;
/*
    定义含有泛型的接口:
        修饰符 interface接口名<代表泛型的变量> {  }
 */
public interface Interface_Generic<T>{
    abstract void show(T t);
}

//==================================
//实现类
package demo3_Generic;
/*
   含有泛型的接口第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型

   举个例子:
   定义一个接口
        public interface Iterator<E>{
            E next();
        }

   Scanner类实现了Iterator接口,并指定接口的泛型为String,所以重写的next方法
   泛型默认就是String类型
        public final class Scanner implements Iterator<String>{
            public String next(){}
        }

*/
public class Interface_GenericImpl implements Interface_Generic<String> {
    @Override
    public void show(String s){
        System.out.println(s);
    }
}

第二种:

//接口
package demo3_Generic;
//定义含有泛型的接口
public interface Interface_Generic2<E> {
   void get(int index);
}

//================================
//实现类
package demo3_Generic;
/*
     含有泛型的接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走,就相当于定义
     了一个含有泛型的类,创建对象的时候确定泛型的类型。

     实例:public interface List<E>{
                E get(int index);
           }
           public class ArrayList<E> implements List<E>{
                @Override
                public E get(int index){}
           }
 */
public class Interface_GenericImpl2<E> implements Interface_Generic2<E>{
    @Override
    public void get(int index){
        System.out.println(index);
    }
}

 测试类:

package demo3_Generic;
//测试含有泛型的接口实现类
public class Interface_GenericImpl_Test {
    public static void main(String[] args) {
        //测试第一种含有泛型的接口使用方式
        Interface_GenericImpl inter=new Interface_GenericImpl();
        inter.show("会发光的小太阳");          //会发光的小太阳

        //测试第二种含有泛型的接口使用方式
        Interface_GenericImpl2<Integer> inter2=new Interface_GenericImpl2<>();
        inter2.get(520);        //520
    }
}

总结

       花了两个多小时整理下今天学的东西,个人觉得关于泛型的定义和使用还算蛮详细的,这一块议自己手动打一遍。关于集合类整理的不是很全面,过两天学习Map和Set,学习过后再把集合类这一块整理一下。


        最近周围毕业的小伙伴陆陆续续的都开始工作,而自己还在培训,有时候总能感觉到和别人的巨大落差,还有就是感觉有时候在一些方向选择总是耽误时间,比如这个培训完全可以在上半年在学校的空白期去培训,这样可以在8月份结束,张阿森他们做选择就干脆果断,3月份就开始培训,下个月就要结束了去搞钱了。
        很想套用插翅难逃里张世豪的一句话:”我现在其他的什么都不想,我就像搞钱,我要变富“。我也想早点找到工作搞钱啊。。。也不知道培训完是什么情况,能不能找到好的工作。
          啥也别想了,现在刚把学费交了,还是先好好学习吧!!!(强行给自己打鸡血---)         
 

猜你喜欢

转载自blog.csdn.net/hpuxiaofang/article/details/81356264
今日推荐