一.泛型
泛型是1.5后的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法.。
1.泛型的优点
①.增加代码的安全性
②.省去了代码的强制转换麻烦(免去了向下转型)
③.可以将错误留在编译期,不会带到实现期.
2.泛型
①.代码说明泛型的代码安全性:
可以让编译器知道执行的数据类型
声明一个集合,保存a,b,c,d
public static void fun1(){
// 泛型是声明集合中保存的元素是什么类型的
// 这个就说明这个集合中保存的元素是String型的
ArrayList<String> arrayList =
new ArrayList<String>();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
Iterator iterator =
arrayList.iterator();
// 正向遍历
while(iterator.hasnext()){
String next = iterator.next();
System.out.println(next);
}
// 反向遍历
while(iterator.hasPrevious()){
String previous =
// 同样的,这个previous也只执行一次
iterator.previous();
System.out.println(previous);
}
}
②.代码说明泛型免向下转型:
集合中保存3个学生对象 迭代器遍历(使用泛型)(详情类见泛型类)
public static void fun2(){
// 1.7后,有菱形泛型 -->
// 后面的泛型可以不写,如果不写,默认和前面的泛型一样;如果写了,前后必须保持一致
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(new Student("stu1",1));
arrayList.add(new Student("stu2",2));
arrayList.add(new Student("stu3",3));
Iterator iterator = arrayList.iterator();
while(iterator.hasnext()){
System.out.println(iterator.next);
}
}
3**.泛型类和泛型方法**
代码举例:
三个类:人类(Person),学生类(Student),工人类(Worker)
(前面两个类全篇都能用到,注意查看)
人类(Person):
public class Person {
private String name;
private int age;
// 构造方法
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// set/get方法
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;
}
// 重写toString方法
@Override
public String toString() {
return "Person [name = " + name + ", age = " + age + "]";
}
}
学生类(Student):
public class Student extends Person implements Compatable<Student>{
public Student() {
}
public Student(String name, int age) {
super(name, age);
}
// 重写comparable接口中的抽象方法
@Override
public int compareTo(Student o){
// 根据年龄大小排序
return this.getAge() - o.getAge();
// 根据姓名排行
return this.getName().compareTo(o.getName());
}
}
工人类(Worker):
泛型方法也包含在其中:
public class Worker<T> {
private T t;
// set/get方法(成员方法)
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
// 泛型的成员方法
// 这里如果写别的泛型的话 没有被赋值 所以会报错
// 此时要先标识出来 在调用这个方法的时候 创建这个泛型
public<W> void sayHi(W t) {
System.out.println(t);
}
// 静态方法的泛型
// 这个E是静态方法自己的泛型
public static<E> void print(E e) {
}
}
创建Worker集合:
泛型类是在创建对象的时候给泛型赋类型的.
Worker<String> worker = new Worker();
worker.setT("lala");
String T = Worker.getT();
System.out.println(T);
Worker.sayHi("你好");
4.泛型接口
泛型通配符:
? entends E –> 向下转型(只允许子类或者孙子类..)
? super E –> 向上转型(只允许父类和祖宗类…)
代码举例:
public static void fun3(){
InterAImpl impl = new InterAImpl();
impl.show("lala");
}
// 泛型直接在接口名后 声明泛型
interface InterA<T>{
public abstract void show(T t);
}
class InterAImpl implements InterA<String>{
@Override
public void show(String t) {
System.out.println(t);
}
}
二.collection中的sort方法
sort是系统给你的方法,那么调用这个sort方法是按照什么排序的呢?
系统是不知道排序的规则的,系统会给你提供一个借口 – comparable,集合中存放什么对象,就让这个对象去实现这个借口,重写里写排序的规则 –> 回调思想.
代码举例:
public static void main(String[] args) {
// 这里是Student对象,所以在Student对象实现接口并重写方法
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(new Student("a",1));
arrayList.add(new Student("b",2));
arrayList.add(new Student("c",3));
arrayList.add(new Student("d",4));
arrayList.add(new Student("e",5));
// 调用系统的排序方法
// 底层调用了你实现接口中的排序规则方法
Collections.sort(arrayList);
System.out.println(arrayList);
}
三.集合的嵌套
见名知意,集合的嵌套就是集合里面套着一个集合
代码举例:
需求:需求:一个java学科 有2个班 每个班里有2个学生 用集合来完成
ArrayList<ArrayList<Student>> java = new ArrayList<>();
// 创建小集合
// 创建班1
ArrayList<Student> j1 = new ArrayList<>();
// 把学生放进班中
j1.add(new Student("张三",18));
j1.add(new Student("李四",19));
// 创建班2
ArrayList<Student> j2 = new ArrayList<>();
// 把学生放进班中
j2.add(new Student("王二",20));
j2.add(new Student("麻子",21));
// 把班级放进学科
java.add(j1);
java.add(j2);
// 遍历学科打印
// 一次循环找出班级
for (ArrayList<Student> j : java) {
// 二层循环找出班级里的学生
for (Student student : j) {
System.out.print(student);
}
System.out.println();
}