首页 > 编程语言 > 详细

19、集合(泛型、泛型类、泛型接口、泛型方法、泛型高级之通配符、增强for、可变参数、Arrays数组工具类的asList(T... t)方法、ArrayList的嵌套)

时间:2020-05-11 22:17:10      阅读:55      评论:0      收藏:0      [点我收藏+]

泛型

泛型概述

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

泛型机制:将数据类型的明确工作推迟到,创建对象或者调用方法时才去明确的机制

泛型好处
(1):把运行时期的问题提前到了编译期间
(2):避免了向下转型
(3):优化了程序设计,解决了黄色警告线

注意:泛型只在编译期有效 但在运行期就擦除了。

package org.westos.demo;

import java.util.ArrayList;

/**
 * @author lwj
 * @date 2020/5/11 19:35
 */
public class MyTest {
    public static void main(String[] args) {
        //泛型机制:将数据类型的明确工作推迟到,创建对象或者调用方法时才去明确的机制
        //泛型:参数化类型
        //泛型可以定义在类、接口和方法上,<类型>,<类型,类型,...> 这些类型必须是引用类型
        //泛型只在编译期有效,在运行期就会被擦除

        //创建集合时使用泛型(没有使用泛型时,集合中可以存储多种引用类型,如果确实想要存储多种引用类型,可以把泛型设置为Object类型)
        ArrayList<String> strings = new ArrayList<>();
        //使用了泛型之后,集合中只能存储字符串类型
        strings.add("aaa");
        //strings.add(12);编译期报错

        String s = strings.get(0);
        //避免了向下转型,从Object类型转为String
        System.out.println(s);
        //aaa
   }
}

ArrayList存储String类型并遍历泛型版

package org.westos.demo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.ListIterator;

/**
 * @author lwj
 * @date 2020/5/11 19:53
 */
public class MyTest2 {
    public static void main(String[] args) {
        ArrayList<String> strings = new ArrayList<>(Arrays.asList("aaa", "bbb", "ccc", "ddd"));
        /*迭代器版本
        ListIterator<String> iterator = strings.listIterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            System.out.println(next);
        }*/
        //aaa
        //bbb
        //ccc
        //ddd

        /* 增强for */
        /* 增强for用于遍历数组和Collection单列集合 */
        for (String string : strings) {
            System.out.println(string);
        }
    }
}

ArrayList存储自定义类型并遍历泛型版

package org.westos.demo;

import java.util.ArrayList;

/**
 * @author lwj
 * @date 2020/5/11 19:52
 */
public class MyDemo {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("张三", 11));
        students.add(new Student("李四", 12));
        students.add(new Student("王五", 13));
        for (Student student : students) {
            System.out.println(student);
        }
        //Student{name=‘张三‘, age=11}
        //Student{name=‘李四‘, age=12}
        //Student{name=‘王五‘, age=13}
    }
}

泛型类

定义格式:

public class 类名<泛型类型1,泛型类型2,…>

注意事项:

泛型的类型必须是引用类型。

package org.westos.demo2;


/**
 * 设计一个泛型类
 * @author lwj
 * @date 2020/5/11 20:02
 */
public class MyClass<E> {
    private E obj;

    public E getObj() {
        return obj;
    }

    public void setObj(E obj) {
        this.obj = obj;
    }
}
package org.westos.demo2;

/**
 * @author lwj
 * @date 2020/5/11 20:04
 */
public class MyTest {
    public static void main(String[] args) {
        MyClass<String> myClass = new MyClass<>();
        myClass.setObj("aaa");
        String obj = myClass.getObj();
        //使用泛型避免了向下转型
        System.out.println(obj);
        //aaa
    }
}

泛型接口

定义格式:

public interface 接口名<泛型类型1,泛型类型2,...>
package org.westos.demo2;

/**
 * @author lwj
 * @date 2020/5/11 20:09
 */
public interface MyInterface<E,T> {
    boolean hasNext();

    E next();

    T show();
}

当使用匿名内部类实现泛型接口:

package org.westos.demo2;

/**
 * @author lwj
 * @date 2020/5/11 20:10
 */
public class MyDemo {
    public static void main(String[] args) {
        //使用匿名内部类
        //在创建时传递泛型类型
        MyInterface<Integer, String> myInterface = new MyInterface<Integer, String>() 		  {

            @Override
            public boolean hasNext() {
                return false;
            }

            @Override
            public Integer next() {
                return null;
            }

            @Override
            public String show() {
                return null;
            }
        };
    }
}

当使用具体类实现泛型接口时:

package org.westos.demo2;

/**
 * @author lwj
 * @date 2020/5/11 20:17
 */
public class MyInterfaceImpl implements MyInterface<Integer, String> {
    @Override
    public boolean hasNext() {
        return false;
    }

    @Override
    public Integer next() {
        return null;
    }

    @Override
    public String show() {
        return null;
    }
}

class MyTest2 {
    public static void main(String[] args) {
        new MyInterfaceImpl();
    }
}

当使用泛型类实现泛型接口时:

package org.westos.demo2;

import java.util.ArrayList;

/**
 * @author lwj
 * @date 2020/5/11 20:19
 */
public class MyInterfaceImpl2<E, T> implements MyInterface<E, T> {
    @Override
    public boolean hasNext() {
        return false;
    }

    @Override
    public E next() {
        return null;
    }

    @Override
    public T show() {
        return null;
    }
}

class MyDemo2 {
    public static void main(String[] args) {
        MyInterfaceImpl2<Integer, String> impl2 = new MyInterfaceImpl2<>();
        //和ArrayList的创建方式一致,ArrayList是泛型类,实现List泛型接口
        //public class ArrayList<E> extends AbstractList<E>
        //        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    }
}

抽象类和普通类一样,可以使用泛型,可以本身使用泛型,也可以继承泛型接口,暂时不声明类型,等到最后创建对象时,和ArrayList一致,再声明类型。

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
public abstract class AbstractCollection<E> implements Collection<E> {}

泛型方法

定义格式:

public <泛型类型> 返回类型 方法名(泛型类型 变量名)
package org.westos.demo3;

/**
 * @author lwj
 * @date 2020/5/11 20:41
 */
public class MyClass {
    /**
     * 泛型方法:public <泛型类型> 返回值类型 方法名(泛型类型 参数名)
     * @param t
     * @param <T>
     */
    public static <T> void show(T t) {
        System.out.println(t.getClass().getName());
        //java.lang.String
        System.out.println(t);
        //aaa
    }
}

class Test {
    public static void main(String[] args) {
        MyClass.show("aaa");
    }
}

泛型高级之通配符

泛型通配符:

<?>

任意类型,如果没有明确,那么就是Object以及任意的Java类。

<? extends E>

向下限定,E和E的子类

<? super E>

向上限定,E和E的父类

package org.westos.demo3;

import java.util.ArrayList;

/**
 * @author lwj
 * @date 2020/5/11 20:46
 */
public class MyTest {
    public static void main(String[] args) {
        ArrayList<?> objects = new ArrayList<Animal>();
        //泛型通配符,代表任意类型
        ArrayList<?> objects1 = new ArrayList<Object>();

        //ArrayList<? extends Animal> list = new ArrayList<Object>();编译报错,不能存储Animal父类
        ArrayList<? extends Animal> list = new ArrayList<Animal>();
        ArrayList<? extends Animal> list1 = new ArrayList<Dog>();
        ArrayList<? extends Animal> list2 = new ArrayList<Cat>();


        ArrayList<? super Animal> list3 = new ArrayList<Animal>();
        ArrayList<? super Animal> list4 = new ArrayList<Object>();
        //ArrayList<? super Animal> list5 = new ArrayList<Dog>();编译报错,不能存储Animal的子类
    }
}

class Animal {

}

class Dog extends Animal {

}

class Cat extends Animal {

}

泛型通配符的应用

package org.westos.demo3;

import java.util.ArrayList;

/**
 * @author lwj
 * @date 2020/5/11 20:56
 */
public class MyTest2 {
    public static void main(String[] args) {
        ArrayList<Integer> integers = new ArrayList<>();
        
        ArrayList<Integer> integers1 = new ArrayList<>();
        
        ArrayList<String> strings = new ArrayList<>();
        
        integers.addAll(integers1);
        //boolean addAll(Collection<? extends E> c)
        //传递一个集合,元素是Integer类及其子类
        
        //integers.addAll(strings);
        //编译报错,required:Collection<? extends E>  provided:ArrayList String
    }
}

增强for

增强for用于简化数组和Collection单列集合的遍历。

定义格式:

for(元素数据类型 变量 : 数组或者Collection集合) {
	使用变量即可,该变量就是元素
}
package org.westos.demo4;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/11 21:02
 */
public class MyTest {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        for (int num : arr) {
            System.out.println(num);
        }

        ArrayList<String> strings = new ArrayList<>(Arrays.asList("aaa", "bbb", "ccc"));
        for (String string : strings) {
            System.out.println(string);
        }
    }
}

快速生成增强for循环

数组名.for
集合名.for

增强for底层用的是迭代器遍历。

所以,在使用增强for遍历时,不能改变容器的长度。

如果在遍历过程中需要改变容器长度,则使用普通for循环,增强for只是简化遍历输出。

package org.westos.demo4;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/11 21:09
 */
public class MyTest2 {
    public static void main(String[] args) {
        ArrayList<String> strings = new ArrayList<>();
        strings.add("aaa");
        strings.add("bbb");
        strings.add("ccc");
        strings.add("ddd");
        System.out.println(strings);
        for (String string : strings) {
            if (string.equals("bbb")) {
                strings.remove(string);
            }
        }
        System.out.println(strings);
    }
}
/*
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
	at java.util.ArrayList$Itr.next(ArrayList.java:859)
	at org.westos.demo4.MyTest2.main(MyTest2.java:18)
*/

可变参数

可变参数概述:定义方法的时候不知道该定义多少个参数。

定义格式:

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

注意事项:

  • 这里的变量其实是一个数组,可以使用增强for
  • 如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个
package org.westos.demo4;

/**
 * @author lwj
 * @date 2020/5/11 21:16
 */
public class MyDemo {
    public static void main(String[] args) {
        int add = add(true, 1, 2, 3, 4, 5);
        System.out.println(add);
        //15
    }

    private static int add(boolean flag, int... i) {
        //如果方法有多个参数,那么可变参数必须放在最后一个
        if (flag) {
            int sum = 0;
            for (int i1 : i) {
                sum += i1;
            }
            return sum;
        }
        return 0;
    }
}

Arrays工具类的asList方法

将数组转换为集合,这个方法含有可变参数,并且是一个泛型方法。

技术分享图片

获取到的这个集合长度是不能改变的,不能给这个集合中添加或者移除元素,只能获取元素。

package org.westos.demo4;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/11 21:24
 */
public class MyDemo2 {
    public static void main(String[] args) {
        ArrayList<String> strings = new ArrayList<>(Arrays.asList("aaa", "bbb", "ccc"));
    }
}
transient Object[] elementData;
//构造方法传入一个集合
public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    //Object[] toArray()
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

ArrayList的嵌套

package org.westos.demo4;

import org.westos.demo.Student;

import java.util.ArrayList;

/**
 * @author lwj
 * @date 2020/5/11 21:36
 */
public class Test {
    public static void main(String[] args) {
        ArrayList<Teenager> teenagers = new ArrayList<>();
        teenagers.add(new Teenager("张三", 12, "六年级"));
        teenagers.add(new Teenager("李四", 11, "六年级"));

        ArrayList<Teenager> teenagers1 = new ArrayList<>();
        teenagers1.add(new Teenager("王五", 9, "四年级"));
        teenagers1.add(new Teenager("赵六", 8, "四年级"));

        ArrayList<ArrayList<Teenager>> arrayLists = new ArrayList<>();
        arrayLists.add(teenagers);
        arrayLists.add(teenagers1);

        for (ArrayList<Teenager> arrayList : arrayLists) {
            for (Teenager teenager : arrayList) {
                System.out.println(teenager);
            }
        }
        //Teenager{grade=‘六年级‘} Student{name=‘张三‘, age=12}
        //Teenager{grade=‘六年级‘} Student{name=‘李四‘, age=11}
        //Teenager{grade=‘四年级‘} Student{name=‘王五‘, age=9}
        //Teenager{grade=‘四年级‘} Student{name=‘赵六‘, age=8}
    }
}

class Teenager extends Student {
    private String grade;

    public Teenager(String name, Integer age, String grade) {
        super(name, age);
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Teenager{" +
                "grade=‘" + grade + ‘\‘‘ +
                "} " + super.toString();
    }
}

19、集合(泛型、泛型类、泛型接口、泛型方法、泛型高级之通配符、增强for、可变参数、Arrays数组工具类的asList(T... t)方法、ArrayList的嵌套)

原文:https://www.cnblogs.com/shawnyue-08/p/12872472.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!