泛型的通配符:?
当操作的不同容器中的类型都不确定的时候,而且使用的都是元素从Object类中继承的方法, 这时泛型就用通配符?来表示即可。(助理解的比方: 泛型中的多态应用)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
public class GenericAdv1 {
@Test
public void demo1(){
List<String> list1 = new ArrayList<String>();
list1.add("aaaa");
list1.add("bbbb");
list1.add("cccc");
Iterator<String> it = list1.iterator();
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}
List<Integer> list2 = new ArrayList<Integer>();
list2.add(100);
list2.add(200);
list2.add(300);
Iterator<Integer> it2 = list2.iterator();
while(it2.hasNext()){
Integer i = it2.next();
System.out.println(i);
}
}
@Test
public void demo2(){
List<String> list1 = new ArrayList<String>();
list1.add("aaaa");
list1.add("bbbb");
list1.add("cccc");
print1(list1);
List<Integer> list2 = new ArrayList<Integer>();
list2.add(100);
list2.add(200);
list2.add(300);
print2(list2);
}
public void print1(List<String> list){
Iterator<String> it = list.iterator();
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}
}
public void print2(List<Integer> list){
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
Integer str = it.next();
System.out.println(str);
}
}
///高级泛型/
@Test
public void demo3(){
List<String> list1 = new ArrayList<String>();
list1.add("aaaa");
list1.add("bbbb");
list1.add("cccc");
print(list1);
List<Integer> list2 = new ArrayList<Integer>();
list2.add(100);
list2.add(200);
list2.add(300);
print(list2);
}
/*写泛型时,想用Object去通吃String、Integer等所有类型。
* 想法很好,但行不通。因为这是多态思想,它是处于"编译+运行期",
* 而泛型只处于"编译期"。
* 泛型中的该“多态”思想是用通配符“?”来实现的。以后记得:
* 泛型中的通吃所有用"?",它类似多态中的"Object"
*/
public void print(List<?> list){
Iterator<?> it = list.iterator();
while(it.hasNext()){
Object str = it.next();
System.out.println(str);
}
}
}
泛型的限定:
对操作的类型限制在一个范围之内。比如:定义一个功能,只操作Person类型或者Person的子类型。这时可以用:
? extends E:接收E类型或者E的子类型。这就是上限。
? super E: 接收E类型或者E的父类型。 这就是下限。
一般情况下:
只要是往容器中添加元素时,使用上限。 ? extends E
只要是从容器中取出元素时,是用下限。 ? super E
演示过程采用了 7个类:
主类:
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;
public class GenericAdv2 {
@Test
public void demo1(){
Set<Student> students = new HashSet<Student>(); //new TreeSet<Student>();
students.add( new Student("小王",22,"计算机"));
students.add( new Student("张三",21,"软件工程"));
students.add( new Student("李四",23,"外语"));
students.add( new Student("老王",22,"电子商务"));
print(students);
Set<Worker> workers = new HashSet<Worker>(); //new TreeSet<Student>();
workers.add( new Worker("Jack",22,"计算机"));
workers.add( new Worker("Tom",21,"软件工程"));
workers.add( new Worker("Mike",23,"外语"));
workers.add( new Worker("Rose",22,"电子商务"));
print(workers);
//Set<Integer> set = new HashSet<Integer>();
//print(set);//编译错误,因为print()方法参数用了“上限”
}
//本例参数中的泛型限制实参必须是Person的子类---高级泛型中的“上限”
public void print(Set<? extends Person> set){
for(Person p:set){
System.out.println(p.getName()+","+p.getAge());
}
}
@Test //使用比较器MyCompByName1 + MyCompByName2
public void demo2(){
Set<Student> students = new TreeSet<Student>( new MyCompByName1() );
students.add( new Student("小王",22,"计算机"));
students.add( new Student("张三",21,"软件工程"));
students.add( new Student("李四",23,"外语"));
students.add( new Student("老王",22,"电子商务"));
print(students);
Set<Worker> workers = new TreeSet<Worker>( new MyCompByName2() );
workers.add( new Worker("Jack",22,"计算机"));
workers.add( new Worker("Tom",21,"软件工程"));
workers.add( new Worker("Mike",23,"外语"));
workers.add( new Worker("Rose",22,"电子商务"));
print(workers);
}
@Test //使用比较器MyCompByName
public void demo3(){
Set<Student> students = new TreeSet<Student>( new MyCompByName() );
students.add( new Student("小王",22,"计算机"));
students.add( new Student("张三",21,"软件工程"));
students.add( new Student("李四",23,"外语"));
students.add( new Student("老王",22,"电子商务"));
print(students);
Set<Worker> workers = new TreeSet<Worker>( new MyCompByName() );
workers.add( new Worker("Jack",22,"计算机"));
workers.add( new Worker("Tom",21,"软件工程"));
workers.add( new Worker("Mike",23,"外语"));
workers.add( new Worker("Rose",22,"电子商务"));
print(workers);
}
}
Person类:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
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;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return name + "," + age;
}
}
Student类:
public class Student extends Person {
private String speciality;
public Student(String name, int age, String speciality) {
super(name, age);
this.speciality = speciality;
}
@Override
public String toString() {
return super.toString() +","+ speciality;
}
}
Worker类:
public class Worker extends Person {
private String job;
public Worker(String name, int age, String job) {
super(name, age);
this.job = job;
}
@Override
public String toString() {
return super.toString() +","+ job;
}
}
MycompByName类:
import java.util.Comparator;
public class MyCompByName implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
return o1.getName().compareTo(o2.getName());
}
}
MycompByName1类:
import java.util.Comparator;
public class MyCompByName1 implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
}
MycompByName2类:
import java.util.Comparator;
public class MyCompByName2 implements Comparator<Worker>{
@Override
public int compare(Worker o1, Worker o2) {
return o1.getName().compareTo(o2.getName());
}
}