java中的泛型
**
* 泛型<>:
* jdk1.5出现 的安全机制
* 注意:泛型里全放的是引用类型的数据,不能放基本数据类型。
* 好处:
* 1.将运行时期的问题ClassCastException转到了编译时期
* 2.避免了转换的麻烦
* <>什么时候用,当操作的引用数据类型不确定 的时候,就使用<>。将要操作的引用数据类型传入即可
* 其实<>就是一个用于接收具体 引用数据类型的参数范围
*
* 在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型
* 泛型技术 是给编译器使用的技术,用于编译时期,确保了类型的安全
* 运行时,会将泛型去掉,生成的class文件中是不带泛型的。这个称为泛型的擦除。
* 因为为了兼容运行时的类加载器。
* 泛型的补偿:在运行时,通过 获取元素的类型进行转换动作,不用使用者再强制转换了
*
* 在jdk1.5后,使用泛型来接收类中要操作的引用数据类型
* 泛型类,什么时候 用?当类中的操作的引用数据不确定 的时候 ,就使用泛型 来表示
*
* 泛型的通配符:?未知类型
*
* 迭代集合中元素
* 可以对类型进行限定:
* ?extends E:接收E类型或者E的子类型对象 ,这叫上限
* ? super E:接收E类型或者E的父类型。下限
*/
一,泛型作用在集合中
// 示例一:
public class GenericDemo {
public static void main(String[] args){
test1();
test2();
test3();
}
private static void test3() {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("aaaa");
arrayList.add("aaaa");
arrayList.add("aaaa");
// Iterator<String> iterator = arrayList.iterator();
// while (iterator.hasNext()){
// String str = iterator.next();
// System.out.println(str);
// }
iter(arrayList);
}
//TreeSet
private static void test2() {
TreeSet<Person> treeSet = new TreeSet<Person>();
treeSet.add(new Person("zhangsan", 10));
treeSet.add(new Person("lisi", 20));
treeSet.add(new Person("wangwu", 20));
treeSet.add(new Person("angwu", 20));
treeSet.add(new Person("zhaoliu", 30));
treeSet.add(new Person("houqi", 30));
iter(treeSet);
}
private static void test1() {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("aaaa");
arrayList.add("bbb");
arrayList.add("ccc");
arrayList.add("ddd");
iter(arrayList);
}
//利用泛型封装成共性方法
private static<T> void iter(Collection<T> treeSet) {
Iterator<T> iterator = treeSet.iterator();
while (iterator.hasNext()){
T t = iterator.next();
System.out.println(t);
}
}
}
示例一打印的结果为:
aaaa
bbb
ccc
ddd
--------------------------
zhangsan:10
angwu:20
lisi:20
wangwu:20
houqi:30
zhaoliu:30
--------------------------
aaaa
aaaa
aaaa
二,泛型作用在类和方法上
示例二:// 工具类中带有泛型
public class Tool<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
//将泛型定义 在方法上
public <R>void show(R str){
System.out.println("show"+str);
}
//当方法静态时,不能访问类上定义 的泛型,如果静态方法使用泛型 ,只能将泛型定义在方法上
public static<Y> void method(Y obj){
System.out.println("method..."+obj);
}
}
public class GenericDemo2 {
public static void main(String[] args){
Tool<Worker> tool = new Tool<Worker>();
tool.setT(new Worker("jjj",22));
Worker worker = (Worker) tool.getT();
System.out.println(worker);
Tool<String> tool1 = new Tool<>();
tool1.show(new Integer(5));
Tool.method("haha");
}
}
示例二打印的结果为:
Worker...jjj:22
show5
method...haha
三,泛型作用在接口上
示例三:接口中带有泛型
public interface Inter<T> {
public void show(T t);
}
class InterImpl2<T> implements Inter<T>{
@Override
public void show(T t) {
System.out.println("show:"+t);
}
}
class InterImpl implements Inter<String>{
@Override
public void show(String s) {
System.out.println("str:"+s);
}
}
public class GenericDemo3 {
public static void main(String[] args){
InterImpl inter = new InterImpl();
inter.show("hdha");
InterImpl2 <String>interImpl2 = new InterImpl2<String>();
interImpl2.show("jjj");
}
}
示例三打印结果为:
str:hdha
show:jjj
四,泛型的通配符,泛型的上限,泛型的下限
//示例四:泛型的通配符
public class GenericAdvanceDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
HashSet<Integer> list2 = new HashSet<>();
list2.add(22);
list2.add(33);
iteratCollection(list);
iteratCollection(list2);
}
private static void iteratCollection(Collection<?> list) {
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
打印结果为:
aaa
bbb
33
22
示例五:泛型的上限和下限
public class GenericAdvanceDemo3 {
public static void main(String[] args) {
ArrayList<Worker> list = new ArrayList<>();
list.add(new Worker("aaa", 22));
list.add(new Worker("bbb", 20));
ArrayList<Person> list2 = new ArrayList<>();
list2.add(new Worker("aaa", 22));
list2.add(new Worker("bbb", 20));
ArrayList<Student> list3 = new ArrayList<>();
list3.add(new Student("aaa", 22));
list3.add(new Student("bbb", 20));
list2.addAll(list3);
iteratCollection(list2);
iteratCollection2(list2);
}
//上限
private static void iteratCollection(Collection<? extends Person> list) {
Iterator<? extends Person> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("----------------------");
}
//下限
private static void iteratCollection2(Collection<? super Person> list) { Iterator<? super Person> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } System.out.println("----------------------"); } //一般在存储元素的时候 都使用上限,因为这样取出都 是按照上限类型来运算的,不会出现安全隐患 class MyCollection<E>{ public void add(E e){ } public void addAll(MyCollection<? extends E> e){ } }}
打印结果为:
Worker...aaa:22
Worker...bbb:20
Student...aaa:22
Student...bbb:20
----------------------
Worker...aaa:22
Worker...bbb:20
Student...aaa:22
Student...bbb:20
----------------------
示例六:泛型的下限使用
在使用TreeSet时,一定要使用比较器
public class GenericAdvanceDemo4 {
public static void main(String[] args) {
TreeSet<Worker> list = new TreeSet<>();
list.add(new Worker("bbb", 20));
list.add(new Worker("aaa", 22));
list.add(new Worker("ccc", 20));
TreeSet<Person> list2 = new TreeSet<>(new CompByName());
list2.add(new Worker("bbb", 20));
list2.add(new Worker("aaa", 22));
list2.add(new Worker("ccc", 20));
TreeSet<Student> list3 = new TreeSet<>();
list3.add(new Student("bbb", 20));
list3.add(new Student("aaa", 22));
list3.add(new Student("ccc", 20));
Iterator<Person> iterator = list2.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
/**
* class TreeSet<Worker>{
* Tree(Comparator<? super Worker>);
* 什么时候用下限呢,通常参集合中的元素进行取出操作时,可以使用下限
* }
*/
class CompByName implements Comparator<Person> {
@Override
public int compare(Person person, Person t1) {
int temp = person.getName().compareTo(t1.getName());
return temp == 0 ? person.getAge() - t1.getAge() : temp;
}
}