12.3.4 泛型集合
- 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致;
- 特点:
编译时即可检查,而非运行时抛出异常;
访问时,不必类型转换(拆箱);
不同泛型之间引用不能相互赋值,泛型不存在多态;
import java.util.List;
import java.util.Vector;
import java.util.ArrayList;
import java.util.LinkedList;
public class TestBasicGeneric {
public static void main(String[] args) {
//数组:元素的类型是一致
Integer[] nums = new Integer[10];
Object[] objs = new Object[10];
//集合:元素的类型可以不一致
List<Student> list = new ArrayList<Student>();
list.add(new Student("tom",18));
list.add(new Student("jack",20));
//list.add(100);//Object o = 100;/Integer.valueOf(100);
//list.add("abc");
//list.add(12345);
//list.add(true);
for(int i = 0 ; i < list.size() ; i++) {
//访问学生的各个属性
Student s = list.get(i);
System.out.println(s.name +"\t"+s.age);
}
List<Integer> numbers = new ArrayList<Integer>();//<E> = Integer
List<String> Vector = new Vector<String>();
List<Double> linkeds = new LinkedList<Double>();
}
}
class Student{
String name;
int age;
public Student(String name , int age) {
this.name = name;
this.age = age;
}
}
运行结果:
tom 18
jack 20
- 泛型:高级类别的知识,熟练应用,需要时间、经验的积累
约束-规范类型
泛型的场景:
定义泛型:
- 实例泛型:
类:创建对象时,为类所定义的泛型,进行参数化赋值;
接口:实现接口时,为接口所定义的泛型,进行参数化赋值;
import java.util.Iterator;
public class TestInstanceGeneric {
public static void main(String[] args) {
MyClass<Integer> mc2 = new MyClass<Integer>();
MyClass<Double> mc3 = new MyClass<Double>();
mc3.println(3.5);
mc2.println(50);
}
}
/*
* 案例1(类的实例泛型)
* */
class MyClass<E>{//E代表一种通配,可以是任意类型,未指明类型前:为Object
public void m1(E e) {//泛型可以动态
}
public void m2(Object o) {//固定写死,不能变
}
public void println(E e) {
//逻辑代码都一样
}
// public void println(Integer i) {
// //逻辑代码都一样
// }
// public void println(String s) {
// //逻辑代码都一样
// }
}
/*
* 案例2(类的实例泛型)
* */
//E = Element / T = Type / K = Kye / V = Value
interface MyInterface<T>{//实例泛型
public T method(T t);
}
class MyLmplClass implements MyInterface<Dog2>{
public Dog2 method(Dog2 t) {
return null;
}
}
class MyLmplClass2 implements MyInterface<Cat2>{
public Cat2 method(Cat2 t) {
return null;
}
}
class Dog2{}
class Cat2{}
interface Comparable2<E>{//可比较,可排序
public int compareTo(E obj);//Object参数的通用,还是在具体业务场景中稍显麻烦
}
class MyStudent implements Comparable2<MyStudent>{
int age;
@Override
public int compareTo(MyStudent obj) {
if(this.age > obj.age) {
return -1;
}
return 0;
}
}
class MyTeacher<T> implements Comparable2<MyTeacher>{
@Override
public int compareTo(MyTeacher obj) {
return 0;
}
public void showInfo(T t) {
}
}
class MyItClass implements Iterator<MyStudent>{
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
@Override
public MyStudent next() {
// TODO Auto-generated method stub
return null;
}
}
- 静态泛型:
定义在方法的返回值类型前面:<T>、<T extends Object>、<T extends Comparable>、<T extends Comparable<? super T>>
定义在方法的形参列表中:<T>、<? extends Object>、<? super Integer>,不支持使用&
import java.util.ArrayList;
import java.util.List;
public class TestStaticGeneric {
public static void main(String[] args) {
List<Dog> list1 = new ArrayList<Dog>();//约束,集合中可以存储的对象
List<Cat> list2 = new ArrayList<Cat>();
List<Bird> list3 = new ArrayList<Bird>();
//List list4 = new ArrayList();//不建议,类型不安全,不一致
List<Bus> list5 = new ArrayList<Bus>();
List<Bicycle> list6 = new ArrayList<Bicycle>();
List<Animal> list7 = new ArrayList<Animal>();
m1(list1);
//m1(list2);//error
//m1(list3);//error
//m1(list4);//error
//m1(list5);//error
//m1(list6);//error
m1(list7);
}
//?代表任意泛型
//可接受的是所有的动物集合
/**
* ? extends Animal 泛型类型必须是Animal的子类
* ? extends Comparable 泛型类型必须是Comparable的实现类
* ? super Dog 泛型类型必须是Dog或Dog父类
*/
public static void m1(List<? super Dog> list) {
//省略
}
}
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
class Bird extends Animal implements Comparable<Bird>{
@Override
public int compareTo(Bird obj) {
return 0;
}
}
class Bus implements Comparable<Bus>{
@Override
public int compareTo(Bus obj) {
return 0;
}
}
class Bicycle{}
泛型参数,约定好规则用以接收相关类型的参数;
import java.io.Serializable;
public class TestStaticGeneric2 {
public static void main(String[] args) {
m1(100);//Integer
m1(12.34);//Double
m1(true);
m1("abc");
m2(56);
m3(new MyNumber());
m4(100);
}
public static void m1(Object t) {//宽泛(特别宽泛,不存在约束了)
}
public static <T extends Object> void m2(T t) {
//此时T的含义是Object
}
public static <T extends Number> void m3(T t) {
//此时T的含义是Number类或者Number的子类
}
public static <T extends Number & Comparable & Serializable> void m4(T t) {
//此时T必须是Number类或者Number的子类的同时也要是Comparable接口的实现类
//父类只有一个,必须写在最前面
}
}
class MyNumber extends Number{
@Override
public int intValue() {
// TODO Auto-generated method stub
return 0;
}
@Override
public long longValue() {
// TODO Auto-generated method stub
return 0;
}
@Override
public float floatValue() {
// TODO Auto-generated method stub
return 0;
}
@Override
public double doubleValue() {
// TODO Auto-generated method stub
return 0;
}
}
向<T>中添加规则来约束泛型的接收范围,约束泛型接收的必须是某个类或其子类;
import java.util.ArrayList;
import java.util.List;
public class TestStaticGeneric3 {
public static void main(String[] args) {
m1(new ArrayList<Integer>());
m1(new ArrayList<Double>());
m1(new ArrayList<String>());
m2(new ArrayList<String>());
m2( new ArrayList<MyClass2>() );
m3( new ArrayList<Double>());
m3( new ArrayList<MyClass3>());
}
public static <T> void m1(List<T> list) {
//此时T代表Object
}
//可以为Comparable约定泛型
public static <T extends Comparable<String>> void m2(List<T> list) {
//此时T代表Comparable接口的实现类,且必须是String泛型
}
public static <T extends Comparable<T>> void m3(List<T> list) {
//此时T代表Comparable接口的实现类,且必须是本身类型泛型
//完成:集合中的所有对象,必须具备本类型的两个元素进行比较
//当List<T>被传入实参后,要求T所代表的类型,必须实现Comparable接口,同时,接口泛型必须是T类型
}
}
class MyClass2 implements Comparable<String>{//和String没有比较的必要,不实际
@Override
public int compareTo(String o) {
// TODO Auto-generated method stub
return 0;
}
}
class MyClass3 implements Comparable<MyClass3>{
@Override
public int compareTo(MyClass3 o) {
// TODO Auto-generated method stub
return 0;
}
}
可以用泛型来约束接收的类型必须是某个接口的实现类
import java.util.ArrayList;
import java.util.List;
public class TestStaticGeneric4 {
public static void main(String[] args) {
List<Student2> students = new ArrayList<Student2>();
students.add(new Student2(20));
students.add(new Student2(18));
students.add(new Student2(22));
List<Teacher> teachers = new ArrayList<Teacher>();
teachers.add(new Teacher(20));
teachers.add(new Teacher(18));
teachers.add(new Teacher(22));
m(students);
m(teachers);
List<Person> persons = new ArrayList<Person>();//Student Teacher
persons.add( new Student2(16) );
persons.add( new Student2(20) );
persons.add( new Teacher(30) );
persons.add( new Teacher(27) );
m(persons);
java.util.Collections.sort(students);
for(int i = 0 ; i < students.size() ; i++) {
System.out.println(students.get(i) +"\t" + students.get(i).age);
}
System.out.println();
java.util.Collections.sort(teachers);
for(int i = 0 ; i < teachers.size() ; i++) {
System.out.println(teachers.get(i) +"\t" + teachers.get(i).age);
}
System.out.println();
java.util.Collections.sort(persons);
for(int i = 0 ; i < persons.size() ; i++) {
System.out.println(persons.get(i) + "\t" + persons.get(i).age);
}
}
/*
* 原案例:当List<T>被传入实参后,要求T所代表的类型,必须实现Comparable接口,同时,接口泛型必须是T类型
*
* 1.如果要求Comparable<T>必须是自身类型,则导致,无法对一组父类引用的对象进行排序,
* 2.故而加入<? super T> 实现Comparable接口时,无论是父类还是子类,都可以成为泛型参数
* */
public static <T extends Comparable<? super T>> void m(List<T> list) {
}
}
class Person implements Comparable<Person>{
int age;
public Person(int age) {
this.age = age;
}
@Override
public int compareTo(Person o) {
if(this.age < o.age) {
return -1;
}else if(this.age > o.age){
return 1;
}
return 0;
}
}
class Student2 extends Person{
public Student2(int age) {
super(age);
}
}
class Teacher extends Person{
public Teacher(int age) {
super(age);
}
}
运行结果:
com.qf.Day24.Student2@7852e922 18
com.qf.Day24.Student2@4e25154f 20
com.qf.Day24.Student2@70dea4e 22
com.qf.Day24.Teacher@5c647e05 18
com.qf.Day24.Teacher@33909752 20
com.qf.Day24.Teacher@55f96302 22
com.qf.Day24.Student2@3d4eac69 16
com.qf.Day24.Student2@42a57993 20
com.qf.Day24.Teacher@75b84c92 27
com.qf.Day24.Teacher@6bc7c054 30
通过泛型约束,避免非法类型的输入;
12.3.5 Colletions工具类
- 概念:集合工具类 ,定义了除了存取以外的集合常用方法;
- 方法:
public static void reverse(List<?> list) //反转集合中元素的顺序
public static void shuffle(List<?> list) //随机重置集合元素的顺序
public static void sort(List list) //升序排序(元素类型必须实现Comparable接口)
public static void <T extends Comparable<? super>> void sort(List list) //元素类型必须实现Comparable接口,可与自身类型比,以及父类类型比)
import java.util.Arrays;
import java.util.List;
public class TestCollectionsTool {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1,2,5,6,4,3,7,9,8);
java.util.Collections.sort(numbers);//升序排序
for(int i = 0 ; i < numbers.size() ; i++) {
System.out.print(numbers.get(i).toString());
}
System.out.println();
java.util.Collections.reverse(numbers);//反转顺序
for(int i = 0 ; i < numbers.size() ; i++) {
System.out.print(numbers.get(i).toString());
}
System.out.println();
java.util.Collections.shuffle(numbers);//随机重置顺序
for(int i = 0 ; i < numbers.size() ; i++) {
System.out.print(numbers.get(i).toString());
}
}
}
输出结果:
123456789
987654321
351246879
通过Collections类可对集合进行灵活操作,可从API上查找方法的具体功能;