学习Java第二十四天--集合框架之泛型集合

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上查找方法的具体功能;

发布了34 篇原创文章 · 获赞 7 · 访问量 1233

猜你喜欢

转载自blog.csdn.net/weixin_44257082/article/details/104682645
今日推荐