java数据类型:集合存储元素类型限制<泛型> ;自定义类指定泛型<T> 以及限制用法;派生子类泛型<T> super(泛型内参数); 泛型通配符?以及?限制用法
问题背景
import java.util.ArrayList;
import java.util.List; public class ProblemTest {
public static void main(String[] args) {
List persons = new ArrayList();
persons.add("李一桐");
persons.add("刘亦菲");
persons.add("鞠婧祎");
//不小心加入了一个int类型的数据
persons.add(10);
persons.forEach(person -> System.out.println(((String) person).length())); //报错int转换不成String报错
}
}
解决:
- 为要存储的元素/变量 灵活指定数据类型
1、泛型使用:
- 作用:<泛型>指定集合存储元素的类型
- 集合类<元素类型..> = new 集合类<>;
Set<String> persons = new HashSet<>();
Map<String, Integer> persons = new HashMap<>();
2、自定义泛型
语法:
自定义类名<泛型形参>{ ... }

我们就是在类名的后面加上类型的替代符,比如上面的T,K,V。我们在使用的时候,就直接把这些T,K,V替换成对应的类型名称就好了。
/**
* @ClassName MyDefineClassInitTypeExample
* @projectName: object1
* @author: Zhangmingda
* @description: 自定义泛型测试
* date: 2021/4/11.
*/
public class MyDefineClassInitTypeExample {
private static class Student<T>{
private T type; public Student(T type) {
this.type = type;
} public T getType() {
return type;
}
}
public static void main(String[] args) {
Student<String> student = new Student<>("高中");
System.out.println(student.getType());//高中
Student<Integer> student1 = new Student<>(202101);
System.out.println(student1.getType());//202101
}
}
3、从泛型类派生子类
语法:
自定义子类名<子类泛型形参> extends 父类名<泛型形参> {
子类构造方法(数据类型|子类泛型形参 形参){
super(形参)
}
}
private static class ElementaryStudent extends Student<T>{
public ElementaryStudent(T type){
super(type);
}
}
public class MyDefineClassInitTypeExample {
private static class Student<T>{
private T type;
public Student(T type) {
this.type = type;
}
public T getType() {
return type;
}
}
private static class ElementaryStudent extends Student<String>{
public ElementaryStudent(String type){
super(type);
}
}
public static void main(String[] args) {
ElementaryStudent elementaryStudent = new ElementaryStudent("小学");
System.out.println(elementaryStudent.getType()); //小学
}
}
定义一个子类的时候,无法指定父类泛型的具体类型:则
/**
* @ClassName MyDefineClassInitTypeExample
* @projectName: object1
* @author: Zhangmingda
* @description: 自定义泛型测试
* date: 2021/4/11.
*/
public class MyDefineClassInitTypeExample {
private static class Student<T>{
private T type; public Student(T type) {
this.type = type;
} public T getType() {
return type;
}
}
private static class ElementaryStudent<T> extends Student<T>{
public ElementaryStudent(T type){
super(type);
}
} public static void main(String[] args) { ElementaryStudent<Integer> elementaryStudent1 = new ElementaryStudent<>(202107);
System.out.println(elementaryStudent1.getType());
}
}
- 用一个支持泛型的类,创建不同类型的实例,他们还是同一个类的实现。
ElementaryStudent<Integer> elementaryStudent1 = new ElementaryStudent<>(202107);
System.out.println(elementaryStudent1.getType());
ElementaryStudent<String> elementaryStudent2 = new ElementaryStudent<>("幼儿园");
System.out.println(elementaryStudent2.getType());
System.out.println(elementaryStudent1.getClass()); //class MyDefineClassInitTypeExample$ElementaryStudent
System.out.println(elementaryStudent2.getClass()); //class MyDefineClassInitTypeExample$ElementaryStudent
System.out.println(elementaryStudent.getClass().equals(elementaryStudent2.getClass()));//true
4、 泛型通配符?
问题:List<Object> 和 List<String> 什么关系,要求传入List<Object> 传入List<String> 行不行?
import java.util.ArrayList;
import java.util.List; public class ProblemTest {
private static void test(List<Object> list) {
for (Object o : list) {
System.out.println(o);
}
}
public static void main(String[] args) {
List<String> persons = new ArrayList<>();
persons.add("李 ");
persons.add("刘 ");
persons.add("祎");
test(persons); //不行,他们是同一类不同的实现,不是子类关系
}
}
解决:用通配符?替代泛型<Object>
import java.util.ArrayList;
import java.util.List; /**
* @ClassName wildcardExample
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/4/11.
*/
public class WildcardExample {
private static void test(List<?> list){
list.forEach(o -> System.out.println(o));
}
public static void main(String[] args) {
List<String> list = new ArrayList();
list.add("张三");
list.add("李四");
test(list);
/**
* 张三
* 李四
*/
}
}
5、限定通配符适配范围
5.1 在List集合使用中限定示例代码:继承Animal类的子类都匹配
语法:
<?extends 类名>
本例如果直接指定List<Animal>泛型,Dog和Cat虽然是Animal的子类,但是List<Dog> List<Cat> 和<List Animal>之间并不是子类关系,List<Dog> 或List<Cat>不能匹配<List Animal>。
import java.util.ArrayList;
import java.util.List; /**
* @ClassName wildcardExample
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/4/11.
*/
public class WildcardLimitExample {
private static class Animal{
public void say(){
System.out.println("动物叫了..........");
}
}
private static class Dog extends Animal{
@Override
public void say() {
System.out.println("I am Dog : 汪汪汪");
}
}
private static class Cat extends Animal{
@Override
public void say() {
System.out.println("I am Cat : 喵喵喵!!!");
}
}
public static void animalSay(List<? extends Animal> animals){
animals.forEach(animal -> animal.say());
}
public static void main(String[] args) {
List<Animal> animals = new ArrayList<>();
animals.add(new Dog());
animals.add(new Cat());
animalSay(animals);
/**
* I am Dog : 汪汪汪
* I am Cat : 喵喵喵!!!
*/
System.out.println("==================="); List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog());
animalSay(dogs);
List<Cat> cats = new ArrayList<>();
cats.add(new Cat());
animalSay(cats);
/**
* I am Dog : 汪汪汪
* I am Cat : 喵喵喵!!!
*/
}
}
5.2在类的定义过程中给泛型限定范围
语法:
修饰符... class<T extends 父类名 [& 接口名] >
- 形参T代表数据类型 extends 后面为T要继承或实现的接口
如下类class CustomerNumber<T extends Number & Serializable> 的意义为:
在用该类创建对象时候如果指定泛型,指定传入构造方法的数据类型T必须是 继承了Number类并且实现了Serializable接口的数据类型。
import java.io.Serializable;
import java.text.NumberFormat; /**
* @ClassName WildcardLimitCustomerNumberExample
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/4/11.
*/
public class WildcardLimitCustomerNumberExample {
private static class CustomerNumber<T extends Number & Serializable>{
private T info; public CustomerNumber(T info) {
this.info = info;
} public T getInfo() {
return info;
}
} public static void main(String[] args) {
CustomerNumber<Integer> customerNumber = new CustomerNumber<>(1);
System.out.println(customerNumber.getInfo());
}
}
java数据类型:集合存储元素类型限制<泛型> ;自定义类指定泛型<T> 以及限制用法;派生子类泛型<T> super(泛型内参数); 泛型通配符?以及?限制用法的更多相关文章
- HashSet集合存储数据的结构和HashSet集合存储元素不重复的原理
HashSet集合存储数据的结构 HashSet集合存储元素不重复的原理 //创建HashSet集合对象 Hashset<String> set = new HashSet<> ...
- JDBC数据类型、Java数据类型、标准sql类型
本概述是从<JDBCTM Database Access from JavaTM: A Tutorial and Annotated Reference>这本书中摘引来的.JavaSoft ...
- JAVA数据类型中的char类型
1.JAVA中,char占2字节,16位.可在存放汉字 2.char赋值 char a='a'; //任意单个字符,加单引号. char a='中';//任意单个中文字,加单引号. char a=11 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_06 Set集合_4_Set集合存储元素不重复的原理
set集合元素为什么不能重复 集合重写了toString的方法所以打印是里面的内容 往里面存了三次abc 哈希表,初始容量是16个 set集合存储字符串的时候比较特殊 横着是数组,竖着就是链表结构.跟 ...
- 向集合中添加自定义类型--建议在自定义类型的时候要重写equals方法
package com.bjpowernode.t01list; import java.util.ArrayList; /* * 向集合中添加自定义类型 */public class TestLis ...
- Java中集合删除元素时候关于ConcurrentModificationException的迷惑点
下面的示例来至于阿里巴巴Java开发手册的集合处理部分的第7条: 运行如下代码,会发现正确运行. public static void hasNotExcption() { List<Strin ...
- Java操作Redis存储对象类型数据
背景描述 关于JAVA去操作Redis时,如何存储一个对象的数据,大家是非常关心的问题,虽然官方提供了存储String,List,Set等等类型,但并不满足我们现在实际应用.存储一个对象是是 ...
- java按照集合中元素的属性进行排序示例代码
public class Student { private String name; private int age; private int id; public Student() { sup ...
- Java 数据类型:集合接口Collection之Set接口HashSet类;LinkedHashSet;TreeSet 类
Collection 之 Set 实现类: HashSet TreeSet 特点: 无序. 元素不可重复. (如果试图添加一个已经有的元素到一个Set集合中,那么会添失败,add()方法返回false ...
随机推荐
- vue create is a Vue CLI 3 only command and you are using Vue CLI 2.9.6. You
这是因为你安装的是2.9的版本用了3.0的命令 解决方法:1.用2.9的命令初始化项目 vue init webpack my-project 2.卸载2.9升级到3.0
- Java 操作符小记
"在最底层,Java中的数据是通过使用操作符来操作的" (Thinking in Java) 1 算术操作符 Java 中的基本算术操作符和其他大多数程序设计语言是相同的.其中包括 ...
- Python的数据解析
- CF187D BRT Contract
考虑如果哪次经过了红灯则显然已经和出发的时间没关系了. 然后我们需要做的是怎么样找到最近的一个是红灯的点. 然后实际下是我们做一个前缀和:\(L_i = \sum d_i\) 然后求\(\min (L ...
- 动态生成多个选择项【c#】
<asp:CheckBoxList ID="cbxLabelList" runat="server" RepeatColumns="10&quo ...
- tensoboard [Errno 22] Invalid argument 以及 Invalid format string问题解决
Invalid argument 问题解决: 需要保证tensorboard与tensorflow版本一致. Invalid format string 问题解决: 修改 manager.py 文件中 ...
- Pytorch学习笔记08----优化器算法Optimizer详解(SGD、Adam)
1.优化器算法简述 首先来看一下梯度下降最常见的三种变形 BGD,SGD,MBGD,这三种形式的区别就是取决于我们用多少数据来计算目标函数的梯度,这样的话自然就涉及到一个 trade-off,即参数更 ...
- day10 负载均衡
day10 负载均衡 负载均衡反向代理 正向代理:即是客户端代理, 代理客户端, 服务端不知道实际发起请求的客户端. # (内部上网) 客户端 <-> 代理 -> 服务端 反向代理即 ...
- 【1】Embarrassingly Parallel(易并行计算问题)
1.什么是Embarrassingly Parallel(易并行计算问题) 易并行计算问题:A computation that can be divided into a number of co ...
- pyqt5 改写函数
重新改写了keyPressEvent() class TextEdit(QTextEdit): def __init__(self): QtWidgets.QTextEdit.__init__(sel ...