Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
常见形式有泛型类、泛型接口、泛型方法。
语法 :
好处:
泛型类: 在类名的后面加上 <>
尖括号, 尖括号中写上类型占位符
eg:
Student<T>
public class Student<T> {
String name;
int age;
//泛型声明成员变量
T t;
//泛型作为方法的参数和返回值
public T sayHi (T t) {
System.out.println("姓名: "+this.name+
"年龄: "+this.age);
return t;
}
}
Test:
public class Test {
public static void main(String[] args) {
Student<String> zhangsan = new Student<>();
zhangsan.t = "hello";
String s = zhangsan.sayHi("hello");
System.out.println(s);
System.out.println("-----------");
Student<Integer> lisi = new Student<>();
lisi.t = 200;
Integer r = lisi.sayHi(200);
System.out.println(r);
}
}
泛型接口: 在接口后面加上<>
, 尖括号中写上类型占位符
eg:
Usb<T>
public interface Usb<T> {
//接口中不能用泛型声明静态常量
//T t;
//泛型作为抽象方法的参数和返回值
T service(T t);
}
Upan Usb<String>
public class Upan implements Usb<String> {
@Override
public String service(String s) {
return s;
}
}
Mouse<E> Usb<E>
public class Mouse<E> implements Usb<E> {
@Override
public E service(E e) {
return e;
}
}
Test:
public class TestUsb {
public static void main(String[] args) {
Usb<String> usb = new Upan();
String s = usb.service("hello");
System.out.println(s);
Usb<String> usb2 = new Mouse<String>();
String s2 = usb2.service("XXXX");
System.out.println(s2);
Usb<Integer> usb3 = new Mouse<Integer>();
Integer r = usb3.service(100);
System.out.println(r);
}
}
泛型方法: 在方法返回值类型的前面加上 <>
尖括号, 尖括号中写上类型占位符
eg:
Teach<T>
public class Teacher {
String name;
//上课
//泛型方法: 在方法返回值类型的前面加上 `<>` 尖括号, 尖括号中写上类型占位符
//泛型作为方法的参数或返回值
public <T> T teach(T t) {
//声明局部变量
T t2 = t;
return t2;
}
//在类中不能使用泛型声明参数个数相同的重载方法。
public <K,E> E teach(E e, K k) {
//声明局部变量
E e1 = e;
return e;
}
}
TestTeach:
public class TestTeach {
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.teach("XXXX");
teacher.teach(1000);
teacher.teach(true);
teacher.teach(Math.PI);
}
}
注意事项:
泛型不能在类中声明静态属性。
- static修饰的属性是静态属性先于对象,泛型类型取决于创建对象时传入的实际类型。
泛型不能在类中初始化对象或数组,但是可以声明引用或数组。
- 实例化对象需要分配空间,没有确定类型不能开辟空间。
- 初始化数组时需要给元素进行分配空间,泛型类型不确定无法分配空间。
在类中不能使用泛型声明参数个数相同的重载方法。
使用不同实际类型创建出的泛型类对象的引用不可以相互赋值。
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
特点:
eg:
TestArrayList :
public class TestArrayList {
public static void main(String[] args) {
//创建集合
//ArrayList list = new ArrayList();
ArrayList<String> list = new ArrayList<>();
//1 添加
list.add("北京");
list.add("上海");
list.add("广州");
//2 遍历
//增强for
for (String s : list) {
System.out.println(s);
}
//普通for
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
//列表迭代器
ListIterator<String> lit = list.listIterator();
while (lit.hasNext()) {
System.out.println(lit.nextIndex()+"..."+lit.next());
}
while (lit.hasPrevious()) {
System.out.println(lit.previousIndex()+"..."+lit.previous());
}
}
}
eg : 泛型通配符 ?
public class Demo01 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
printList(list);
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(111);
list1.add(222);
printList(list1);
}
//方法1: 使用泛型方法
/*
public static <T> void printList(ArrayList<T> list) {
for (Object o : list) {
System.out.println(o);
}
}
*/
//方法2: 使用泛型通配符 ? 表示任何类型
/*
泛型通配符的限制
1 泛型上限: ? extends Student ?只能是Student类型或Student的子类
2 泛型下限: ? super Student ?只能是Student类型或Student的父类
*/
public static void printList(ArrayList<?> list) {
for (Object o : list) {
System.out.println(o);
}
}
}
概念:集合工具类,定义了除了存取以外的集合常用方法。
常用方法:
eg:
public class TestCollection {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(8);
list.add(20);
list.add(12);
list.add(3);
list.add(3);
list.add(3);
list.add(3);
//1 sort(); 排序
Collections.sort(list);
System.out.println("排序之后: "+list);
//2 binarySearch(); 二分查找
int pos = Collections.binarySearch(list, 5);
System.out.println(pos);
//3 copy(); 复制
List<Integer> list2 = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
list2.add(0);
}
Collections.copy(list2,list);
System.out.println(list2);
//4 frequency(); 获取元素出现的次数
int count = Collections.frequency(list, 3);
System.out.println(count);
//5 reverse(); 反转
Collections.reverse(list);
System.out.println(list);
//6 shuffle(); 打乱元素
Collections.shuffle(list);
System.out.println("打乱之后: "+list);
}
}