Java.SE.09.泛型


typora-root-url: imgs
typora-copy-images-to: imgs

JavaSE.09.泛型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GcgMKdVf-1605171901981)(/image-20201112160249112.png)]

1.泛型

1.泛型的使用
泛型:标签
把元素的类型设计成一个参数,这个类型参数叫做泛型

泛型的使用
1.jdk5.0新增
2.在集合中使用泛型
		总结:
		①集合接口或集合类在jdk5.0时都修改为带泛型的结构
		②在实例化集合类时,可以指定具体的泛型类型
		③jdk5.0以后在集合类或接口中凡是定义类或接口时,内部结构使用到类的泛型的位置,都指定为实例化的泛型类型
		比如:add(E e) --> 实例化以后:add(Integer e)
		④注意点:泛型的类型必须是类,不能是基本数据类型,需要用到基本数据类型,用包装类替换
		⑤如果实例化时,没有指明泛型的类型,默认类型为java.lang.Object类型
	ArrayList<Integer> list = new ArrayList<>();jdk7类型推断:泛型只需显示的定义前一个
3.注意:静态方法不可以使用泛型,静态结构早于对象的创建,故不可以使用泛型
		异常类不能使用泛型
public class GenericTest {
	// 在集合中使用泛型之前的情况
	// 问题1:类型不安全
	// 问题2:强转时,可能出现ClassCastException
	@Test
	public void test1() {
		ArrayList<Integer> list = new ArrayList<>();
		list.add(78);
		list.add(22);
		list.add(11);
		list.add(55);

//		list.add("Tom");//加上泛型以后规范装入的数据
		// The method add(Integer) in the type ArrayList<Integer> is not applicable for
		// the arguments (String)

//		for (Integer score : list) {
//			int stuScore = (Integer)score;
//			System.out.println(stuScore);
//		}
		Iterator<Integer> iterator = list.iterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next());
		}

	}
2.自定义泛型
@Test
	public void test2() {
		// 如果自定义了泛型类,实例化没有指明类的泛型,则认为此泛型类型为Object类型
		// 要求:如果实例化的类带有泛型,那么实例化时应指出泛型
		Order o = new Order();
		o.setOrderT(444);
		o.setOrderT("123");
		System.out.println(o.getOrderT());

		// 实例化时指明泛型的类型
		Order<String> o1 = new Order<>();
		o1.setOrderT("123");
		System.out.println(o1.getOrderT());

		// 自定义类的父类已经定义泛型,则子类不需要定义泛型,使用父类的泛型
		SubOrder s = new SubOrder();

		SubOrder1<String> s2 = new SubOrder1<>();

	}
/*
 * 自定义泛型
 */
public class Order<T> {
	String orderName;
	int orderId;
	//类的内部结构就可以使用类的泛型
	T orderT;
	public Order() {
		
	}
	public Order(String orderName, int orderId, T orderT) {
		super();
		this.orderName = orderName;
		this.orderId = orderId;
		this.orderT = orderT;
	}
	public String getOrderName() {
		return orderName;
	}
	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}
	public int getOrderId() {
		return orderId;
	}
	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
	public T getOrderT() {
		return orderT;
	}
	public void setOrderT(T orderT) {
		this.orderT = orderT;
	}
	
	//自定义泛型方法:在方法中出现了泛型的结构,泛型的参数与类的泛型参数没有任何关系
	//泛型方法所属的类是不是泛型类都没有关系
	public <E> List<E> copyArrayToList(E[] arr) {
		ArrayList<E> list = new ArrayList<>();
		for(E e : arr) {
			list.add(e);
		}
		return list;
	}
}
3.泛型方法
泛型方法
泛型方法可以声明为static静态的
	@Test
	public void test3() {
		Order<String> o = new Order<>();
		Integer[] arr = new Integer[] {1,2,3,4};
		List<Integer> list = o.copyArrayToList(arr);
		for (Object object : list) {
			System.out.println(object);
		}
	}
	
	//自定义泛型方法:在方法中出现了泛型的结构,泛型的参数与类的泛型参数没有任何关系
	//泛型方法所属的类是不是泛型类都没有关系
	public <E> List<E> copyArrayToList(E[] arr) {
		ArrayList<E> list = new ArrayList<>();
		for(E e : arr) {
			list.add(e);
		}
		return list;
	}
4.泛型的继承
泛型在继承方面的体现
类A是类B的父类,G<A> , G<B>二者不具备子父类关系,二者是并列的关系
类A是类B的父类,A<G> , B<G>二者具备子父类的关系
@Test
	public void test4() {
		Object obj = null;
		String str = null;
		obj = str;
		
		Object[] obj1 = null;
		String[] str1 = null;
		obj1 = str1;
		
		List<Object> list1 = null;
		List<String> list2 = null;
		//不具备子父类关系,反证法说明
//		list1 = list2;//Type mismatch: cannot convert from List<String> to List<Object>
		
		Order<String> o1 = null;
		SubOrder1<String> o2 = null;
		o1 = o2;
		
	}

public class SubOrder extends Order<Integer>{

}

public class SubOrder1<T> extends Order<T>{//SubOrder1<T>不是泛型类

}

2.通配符

1.通配符的使用
通配符的使用
通配符:?
类A是类B的父类,G<A>和G<B>是没有关系的,二者共同的父类是:G<?>
	@Test
	public void test1() {
		List<Object> list1 = null;
		List<String> list2 = null;
		
		List<?> list = null;
		
		list = list1;
		list = list2;
		
		//
		List<String> list3 = new ArrayList<>();
		list3.add("AAA");
		list3.add("bbb");
		list3.add("CCC");
		list3.add("EEE");
		list = list3;
		
		//添加(写入):对于List<?>就不能向其内部添加数据
		//除了添加null之外
//		list.add("DD");
		list.add(null);
		
		//获取(读取):对于List<?>允许读取数据,读取的数据类型为Object
		Object obj1 = list.get(0);
		System.out.println(obj1);
		
	}
	
	public void print(List<?> list) {
		Iterator<?> iterator = list.iterator();
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}
	}
3.有限制条件的通配符的使用
? extends A : G<? extends A>可以作为G<A>和G<B>的父类的,其中B是A的子类
 		
? super A : G<? super A>可以作为G<A>和G<B>的父类,其中B是A的父类
@Test
	public void  test2() {
		List<? extends Person> list1 = null;// ? << Student < Person
		List<? super Person> list2 = null;//Person  << ? < Object
		
		List<Student> list3 = null;
		List<Person> list4 = null;
		List<Object> list5 = null;
		
		list1 = list3;
		list1 = list4;
//		list1 = list5;//Type mismatch
		
//		list2 = list3;//Type mismatch
		list2 = list4;
		list2 = list5;
		
		//读取数据:
		list1 = list3;
		Person p = list1.get(0);
		Object o = list1.get(0);
		//编译不通过
//		Student s = list1.get(0);
		
		list2 = list4;
		Object obj = list2.get(0);
		//编译不通过
//		Person p2 = list2.get(0);
		
		//写入数据:
		//编译不通过
		List<? extends Person> list11 = null;
//		list11.add(new Student());
		
		//
		list2.add(new Person());
		list2.add(new Student());
//		list2.add(new Object());
	}

public class Person {

}

public class Student extends Person{

}

练习:

/*
 * 自定义泛型类
 */
public class DAO<T> {
	
	private Map<String,T> map = new HashMap<>();
	
	//保存T类型的对象到Map成员变量中
	public void save(String id,T entity) {
		map.put(id, entity);
	}
	
	//从map中获取id对应的对象
	public T get(String id) {
		return map.get(id);
	}
	
	//替换map中key为id 的内容,改为entity对象
	public void update(String id,T entity) {
		if(map.containsKey(id)) {
			map.put(id, entity);
		}
	}
	
	//返回map中存放的所有的T对象
	public List<T> list(){
		//错误的
//		Collection<T> list = map.values();
//		return (List<T>) list;
		//正确
		ArrayList<T> list = new ArrayList<>();
		Collection<T> values = map.values();
		for(T t : values) {
			list.add(t);
		}
		return list;
	}
	
	//删除指定id对象
	public void delete(String id) {
		map.remove(id);
	}
}
public class User {
	
	private int id;
	private int age;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public User() {
		super();
	}
	public User(int id, int age, String name) {
		super();
		this.id = id;
		this.age = age;
		this.name = name;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", age=" + age + ", name=" + name + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (age != other.age)
			return false;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
}
public class DAOTest {
	public static void main(String[] args) {
		DAO<User> dao = new DAO<>();
		dao.save("1001", new User(1001,34,"周杰伦"));
		dao.save("1002", new User(1002,20,"张曼玉"));
		dao.save("1003", new User(1003,18,"张国荣"));
		
		dao.update("1003", new User(1003,30,"方文山"));
		
		List<User> list = dao.list();
		list.forEach(System.out::println);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值