JAVASE-19:泛型、增强for、可变参数和asList()方法的使用


1.泛型概述和基本使用

泛型:
JDK1.5之后引入的一种机制。是一种把类型明确的工作,推迟到创建对象或者调用方法的时候,才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。

泛型的格式:
<数据类型> 这里的数据类型只能是引用数据类型

泛型好处:
(1): 把运行时期的问题提前到了编译期间;
(2): 避免了强制类型转换、向下转型;
(3): 优化了程序设计,解决了黄色警告线,提高代码的扩展性。
注意:泛型只在编译期有效 但在运行期就擦除了。

泛型基本使用:

public static void main(String[] args) {
    ArrayList<String> list2 = new ArrayList<String>();
    list2.add("abc");
    // list2.add(100);报错
    String s = list2.get(0);
    System.out.println(s);
}
ArrayList存储自定义对象并遍历泛型版:
public static void main(String[] args) {
    ArrayList<Student> list = new ArrayList<>();
    list.add(new Student("张国荣",23));
    list.add(new Student("张国荣", 23));
    list.add(new Student("张家辉", 23));
    list.add(new Student("张震岳", 23));
    list.add(new Student("张子豪", 23));
    /*   
    Iterator iterator = list.iterator();
    while (iterator.hasNext()) {
        Student student = (Student) iterator.next();
        System.out.println(student);
    }*/
    Iterator<Student> iterator = list.iterator();
    while (iterator.hasNext()) {
        Student student = iterator.next();
        System.out.println(student);
    }
}
泛型的由来:

通过Object转型问题引入,早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。

泛型类的使用:

把泛型定义在类上
定义格式: public class 类名<泛型类型1,…>
注意事项: 泛型类型必须是引用类型

public class MyClass<T> {
    private T t;
    private Integer num;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}
泛型方法的使用:

把泛型定义在方法上
定义格式: public <泛型类型> 返回类型 方法名(泛型类型 变量名)
案例演示: 泛型方法的使用

public static void main(String[] args) {
    MyObjct<String, Integer> stringIntegerMyObjct = new MyObjct<>();
    stringIntegerMyObjct.setU(100);
    stringIntegerMyObjct.setR("abc");

    String r = stringIntegerMyObjct.getR();
    Integer u = stringIntegerMyObjct.getU();
}
public class MyObjct<R,U> {
    private R r;
    private U u;

    public R getR() {
        return r;
    }

    public void setR(R r) {
        this.r = r;
    }

    public U getU() {
        return u;
    }

    public void setU(U u) {
        this.u = u;
    }
}
泛型接口使用:

把泛型定义在接口上
定义格式: public interface 接口名<泛型类型>
案例演示: 泛型接口的使用

public interface MyInterface<A> {
    public abstract void test(A a);
}
//子类实现接口时,可以明确接口上的泛型具体是什么类型
public class MyA implements MyInterface<Integer>{
    @Override
    public void test(Integer integer) {
        System.out.println("abc");
    }
}
public static void main(String[] args) {
    //采用匿名 内部类的这种方式,在创建接口的子类对象时,可以明确接口上的泛型具体是什么类型。
    new MyInterface<String>(){
        @Override
        public void test(String s) {

        }
    };
    MyB<Double> doubleMyB = new MyB<>();
}
泛型高级之通配符
<?>: 任意类型,如果没有明确,那么就是Object以及任意的Java类了,? 表示任意的数据类型

? extends E: 向下限定,E及其子类, ? 表示的是E或者E的子类
? super E: 向上限定,E及其父类, ? 表示的是E或者E的父类

泛型如果明确了数据类型以后,那么要求左右两边的数据类型必须一致

public class MyTest {
    public static void main(String[] args) {
        //? 泛型通配符
        ArrayList<?> objects = new ArrayList<Dog>();
        ArrayList<?> objects2 = new ArrayList<Cat>();
        ArrayList<?> objects3 = new ArrayList<Animal>();
        System.out.println("====================================");
        //向上限定
        ArrayList<? super Cat> list = new ArrayList<Animal>();
        ArrayList<? super Animal> list2 = new ArrayList<Animal>();
        ArrayList<? super Animal> list3 = new ArrayList<Object>();
        //向下限定
        ArrayList<? extends Animal> list4 = new ArrayList<Animal>();
        ArrayList<? extends Animal> list5 = new ArrayList<Cat>();
        ArrayList<? extends Animal> list6 = new ArrayList<Dog>();

        System.out.println("============================================");

        ArrayList<Integer> a= new ArrayList<>();
        a.add(200);
        ArrayList<Integer> b = new ArrayList<>();
        b.add(2000);
        a.addAll(b);
    }
}
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{

}

2.增强for的概述和使用

简化数组和Collection集合的遍历

格式:
for(元素数据类型 变量 : 数组或者Collection集合) {
使用变量即可,该变量就是元素
}

注意事项:
增强for的目标要判断是否为null;
注意新式for循环,你在迭代集合的途中,不能增删元素,会报并发修改异常

public static void main(String[] args) {
    // 新式 for循环 JDK1.5 引入的语法
    int[] arr={20,30,50};
    // for(容器中的元素的数据类型 变量名:容器名)
    for(int a:arr){
        System.out.println(a);
    }

    System.out.println("==============================");

    ArrayList<Integer> integers = new ArrayList<>();
    integers.add(200);
    integers.add(200);
    integers.add(200);
    integers.add(200);
    for(Integer num:integers){
        System.out.println(num);
    }

    System.out.println("===============================");
    for (int i : arr) {
    }
    for (Integer integer : integers) {
    }
}
ArrayList存储字符串并遍历增强for版
public static void main(String[] args) {
    ArrayList<Integer> integers = new ArrayList<>();
    integers.add(200);
    integers.add(200);
    integers.add(200);
    integers.add(200);
    //ConcurrentModificationException 并发修改异常
    //新式for循环在遍历集合时,底层用的还是迭代器,你在遍历途中,如果改变集合的长度,就会报并发修改异常。
    for (Integer integer : integers) {
        if(integer.intValue()==200){
            integers.add(300);
        }
    }
    System.out.println(integers);
}

3.可变参数的概述和使用

定义方法的时候不知道该定义多少个参数

格式:
修饰符 返回值类型 方法名(数据类型… 变量名){}

注意事项:
a: 这里的变量其实是一个数组
b: 如果一个方法有可变参数,并且有多个参数,那么可变参数肯定是最后一个

public static void main(String[] args) {
    int sum = add(1, 2);
    int sum2 = add(1, 2, 3);
    int sum3 = add(1, 2, 3, 4);

    System.out.println(sum);// 3
    System.out.println(sum2);// 6
    System.out.println(sum3);// 9
}

//可变参数,一次可以接收多个同类型的参数
//可变参数 本质是是个数组
//如果一个方法的形参有多个参数,那么可变参数,应该是最后一个。
private static int add(int b,int... a) {
    //System.out.println(a.length);
    int sum=b;
    for (int i : a) {
        sum += i;
    }
    return sum;
}

4.Arrays工具类的asList()方法的使用

将数组转换成集合

注意事项:
得到的集合长度是不可变的,你不能往这个转换后的集合中 添加元素(add) 和 删除元素(remove),只能获取元素(get)。

public static void main(String[] args) {
    //把一个数组转换集合。
    int[] arr={20,30,40};
    //我传的是一个基本类型的数组,他是把这个数组对象,放到集合中
    List<int[]> ints = Arrays.asList(arr);
    System.out.println(ints);
    System.out.println(ints.get(0)[0]);

    Integer[] arr2 = {20, 30, 40};
    //我传入的是一个包装类型的数组,他是把数组中的元素,取出来放到集合中
    List<Integer> integers = Arrays.asList(arr2);
    System.out.println(integers);

    Integer[] arr3 = {20, 30, 40};
    Integer[] arr4 = {20, 30, 400};
    //如果你传入多个包装类型的数组,那么他是把多个数组对象,放到集合中。
    List<Integer[]> integers1 = Arrays.asList(arr3, arr4);
    Integer integer = integers1.get(1)[2];
    System.out.println(integer);
    
    //也可以这样得到一个集合。
    List<Integer> integers2 = Arrays.asList(20, 20, 30, 50, 30);
    System.out.println(list.get(0));
    //list.add(300);
    //UnsupportedOperationException
    //list.remove(0);
    //注意:通过Arrays.asList() 这种方式的得到集合,不能再次改变集合的长度,也就是说,你不能增删元素。
}
集合嵌套之ArrayList嵌套ArrayList

A:需求:
我们班有学生,每一个学生是不是一个对象。所以我们可以使用一个集合表示我们班级的学生ArrayList< Student >
但是我们旁边还有班级,每个班级也是一个ArrayList< Student >。
而我现在有多个ArrayList< Student >。也要用集合存储,怎么办呢?
------集合嵌套之ArrayList嵌套ArrayList

​ // 定义大的集合
​ ArrayList<ArrayList> allClassList = new ArrayList<ArrayList>() ;

​ // 创建每一个班的集合
​ ArrayList jcClassList = new ArrayList() ;

public class MyTest {
    public static void main(String[] args) {
        Student C = new Student("C罗", 28);
        Student B1 = new Student("贝尔", 24);
        Student B2 = new Student("本泽马", 26);

        Student M = new Student("梅西", 26);
        Student S = new Student("苏亚雷斯", 26);
        Student N = new Student("内马尔", 22);
        ArrayList<ArrayList<Student>> students = new ArrayList<>();
        ArrayList<Student> HM = new ArrayList<>();
        ArrayList<Student> BS = new ArrayList<>();
        HM.add(C);
        HM.add(B1);
        HM.add(B2);
        BS.add(M);
        BS.add(S);
        BS.add(N);
        students.add(HM);
        students.add(BS);

        for (ArrayList<Student> student : students) {
            for (Student student1 : student) {
                System.out.println(student1.getName() + "===" + student1.getAge());
            }
            System.out.println();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值