java笔记--Collection集合框架三

泛型:

jdk1.5出现的安全机制。

好处:

1,将运行时期的问题ClassCastException转到了编译时期。
2,避免了强制转换的麻烦。

<>:什么时候用?当操作的引用数据类型不确定的时候。就使用<>.将要操作的引用数据类型传入即可。其实<>就是一个用于接受具体引用数据类型的参数范围。

在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型。

泛型技术是在给编译器使用的技术,用于编译时期。确保了类型的安全。

运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。
为什么擦除?因为为了兼容运行的类加载器。

泛型的补偿:在运行时,通过获取元素的类型进行转换动作。不用使用者在强制转换了。

共用类:

Person:

public class Person implements Comparable{

    @Override
    public String toString() {
        return "Person" + name + ":" + 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;
    }

    private String name;
    private int age;
    
    public Person() {
        super();
    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    
    public int compareTo(Person p){
        int temp=this.age-p.age;
        return temp==0?this.name.compareTo(p.name):temp;
    }
    
    @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;
    }
}

Student:

public class Student extends Person{
    
    @Override
    public String toString() {
        return "Student:" + getName() + ":" + getAge();
    }

    public Student(){
        super();
    }

    public Student(String name, int age) {
        super(name, age);
        
    }
}

Worker:

public class Worker extends Person{

    @Override
    public String toString() {
        return "Worker" + getName() + ":" + getAge();
    }

    public Worker(){
        super();
    }
    
    public Worker(String name,int age){
        super(name,age);
    }
}

ComparatorByName:

public class ComparatorByName implements Comparator{

    @Override
    public int compare(Person o1, Person o2) {

        int temp=o1.getName().compareTo(o2.getName());
        return temp==0?o1.getAge()-o2.getAge():temp;
    }
}

GenericDemo:

public static void main(String[] args) {
        
        int[] arr=new int[4];
        
        ArrayList al=new ArrayList();

        al.add("abc");
        al.add("hahah");
        
        
        Iterator it=al.iterator();
        while(it.hasNext()){
            
            String str=it.next();
            System.out.println(str);
        }
    }

运行:

GenericDemo2:

public static void main(String[] args) {
        
        TreeSet ts =new TreeSet(new ComparatorByName());
        ts.add(new Person("lisi8",21));
        ts.add(new Person("lisi3",23));
        ts.add(new Person("lisi",21));
        ts.add(new Person("lisi0",20));
        
        Iterator it=ts.iterator();
        while(it.hasNext()){
            Person p=it.next();
            System.out.println(p.getName()+":"+p.getAge());
        }
    }

运行:
那么用泛型操作不确定引用类型的数据呢?

以前的做法是把所有共性取出来,所以所有对象都可以往里面存。即用Object定义一个对象。

在jdk1.5以后,使用泛型来接受要操作的引用数据类型--即泛型类。

什么时候用?
当类中操作的引用数据类型不确定的时候,就使用泛型来表示。这样做比Object安全得多。

Tool:

/*
public class Tool {
    以前是把所有共性都取出来,所以所有对象都可以往里面存
    private Object object;
    
    public void setObject(Object object) {
        this.object = object;
    }

    
    
    public Object getObject(){

        return object;
    }
}
*/
/*
在jdk1.5后,使用泛型来接受类中要操作的引用数据类型。
即泛型类。什么时候用?当类中操作的引用数据类型不确定的时候,就使用泛型来表示。
这么做比Object要安全得多。
*/
public class Tool{
    private QQ q;
    
    public QQ getObject() {
        return q;
    }

    public void setObject(QQ Object) {
        this.q = Object;
    }
    /*
    将泛型定义在方法上
    */
    public  void show(W str){
        System.out.println("show:"+str.toString());
    }
    public void print(QQ str){
        System.out.println("print:"+str);
    }
    /*
    当方法静态时,不能访问类上定义的泛型。如果静态方法使用泛型,只能将泛型定义在方法上。
    */
    public static  void method(Y obj){
        System.out.print("method"+obj);
    }
}

GenericDefineDemo:

public static void main(String[] args) {
        //以前的做法
        /*Tool tool=new Tool();
        
        tool.setObject(new Worker());
        Student stu=(Student) tool.getObject();*/
        
        //1.5以后
        Tool tool=new Tool();
        tool.setObject(new Student("kk",21));
        Student stu =tool.getObject();
        System.out.print(tool.getObject());
    }

运行:
将泛型定义在方法上。

GenericDefineDemo2:

public static void main(String[] args) {
        
        Tool tool=new Tool();

        tool.show(new Integer(4));
        tool.show("abc");
        tool.print("haha");
//      tool.print(new Integer(4));报错,因为此方法没有用泛型定义
        
        Tool.method("haha");
        Tool.method(new Integer(9));
    }

运行:
java笔记--Collection集合框架三_第1张图片
将泛型定义在接口上。

GenericDefineDemo3:

public class GenericDefineDemo3 {

    public static void main(String[] args) {
        InterImpl in=new InterImpl();
        in.show("abc");
        
        InterImpl2 in2=new InterImpl2();
        in2.show(5);

    }

}

//泛型接口,将泛型定义在接口上。
interface Inter{
    public void show(T t);
}

class InterImpl implements Inter{
    public void show(String str){
        System.out.println("show:"+str);
    }
}

class InterImpl2 implements Inter{
    public void show(Q q){
        System.out.println("show:"+q);
    }

运行:

泛型的通配符:? 未知类型。

GenericAdvanceDemo:

public static void main(String[] args) {
        
        ArrayList al=new ArrayList();
        
        al.add("abc");
        al.add("hehe");
        
        ArrayList al2=new ArrayList();
        
        al2.add(5);
        al2.add(87);
        
        printCollection(al);
        printCollection(al2);
    }

//  迭代并打印集合中的元素
//  通配符?的使用
    private static void printCollection(Collection al) {
        
        Iterator it=al.iterator();
        while(it.hasNext()){
            System.out.println(it.next().toString());
        }
    }

运行:
泛型的限定:

? extends E:接受E类型或者E的子类对象。上限。

? super E:接受E类型或者E的父类型对象。下限。

GenericAdvanceDemo2:

public static void main(String[] args) {
        ArrayList al=new ArrayList();
        
        al.add(new Person("abc",30));
        al.add(new Person("abc4",34));
        
        ArrayList al2=new ArrayList();
        
        al2.add(new Student("stu1",11));
        al2.add(new Student("stu2",22));
        
        ArrayList al3=new ArrayList();
        
        al3.add("stu3331");
        al3.add("stu3332");
        
        printCollection(al);
        printCollection(al2);
    }
    /*
    迭代并打印集合中的元素
    通配符?的使用
    
    可以对类型进行限定:
    ? extends E:接受E类型或者E的子类型对象。上限!
    
    ?  super E:接受E类型或者E的父类型。下限!
    */
/*  
    private static void printCollection(Collection al) {
        
        Iterator it=al.iterator();
        while(it.hasNext()){
            Person p=it.next();
            System.out.println(p.getName()+":"+p.getAge());
        }
    } 
*/

    private static void printCollection(ArrayList al) {
        Iterator it=al.iterator();
        
        while(it.hasNext()){
            System.out.println(it.next());
        }
        
    }

运行:
java笔记--Collection集合框架三_第2张图片
一般存储对象的时候用上限。比如 添加元素 addAll。

GenericAdvanceDemo3:

public static void main(String[] args) {
        
        ArrayList al1=new ArrayList();

        al1.add(new Person("abc",30));
        al1.add(new Person("abc4",34));
        
        ArrayList al2=new ArrayList();
        
        al2.add(new Student("stu1",11));
        al2.add(new Student("stu2",22));
        
        ArrayList al3=new ArrayList();
        
        al3.add(new Worker("stu1",11));
        al3.add(new Worker("stu2",22));
        
        ArrayList al4=new ArrayList();
        al4.add("anbc");
//      al1.addAll(al4);错误,类型不匹配
        
        al1.addAll(al2);
        al1.addAll(al3);
        
        
        System.out.print(al1.size());

    }
一般取出对象的时候用下限。比如 比较器。
public class GenericAdvanceDemo4 {

    public static void main(String[] args){
        
        TreeSet al1=new TreeSet(new CompByName());
        
        al1.add(new Person("abc4",34));
        al1.add(new Person("abc1",30));
        al1.add(new Person("abc2",38));
        
        TreeSet al2=new TreeSet(new CompByName());
        
        al2.add(new Student("stu1",11));
        al2.add(new Student("stu2",22));
        al2.add(new Student("stu7",20));
        
        TreeSet al3=new TreeSet();
        
        al3.add(new Worker("stu1",11));
        al3.add(new Worker("stu2",22));
        
        TreeSet al4=new TreeSet();
        al4.add("abchd");
        
        Iterator it =al2.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}
/*
    class TreeSet{
        Tree(Comparator comp);
    }

    什么时候用下限呢?通常对集合中的元素进行取出操作时,可以用下限

*/
class CompByName implements Comparator{

    @Override
    public int compare(Person o1, Person o2) {
        int temp=o1.getName().compareTo(o2.getName());
        return temp==0?o1.getAge()-o2.getAge():temp;
    }
}   
class CompByStuName implements Comparator{

    @Override
    public int compare(Student o1, Student o2) {
        int temp=o1.getName().compareTo(o2.getName());
        return temp==0?o1.getAge()-o2.getAge():temp;
    }
}
class CompWorkerName implements Comparator{

    @Override
    public int compare(Worker o1, Worker o2) {
        int temp=o1.getName().compareTo(o2.getName());
        return temp==0?o1.getAge()-o2.getAge():temp;
    }   
}

运行:
通配符“?”的体现:containsAll(),removeAll()等。

GenericAdvanceDemo5:

public static void main(String[] args) {
        
        ArrayList al1=new ArrayList();

        al1.add(new Person("abc",30));
        al1.add(new Person("abc4",34));
        
        ArrayList al2=new ArrayList();
        al2.add(new Person("abc22222",30));
        al2.add(new Person("abc4222222",34));
        
        ArrayList al4=new ArrayList();
        al4.add("abcdef");
        al4.add("abc");
        
        al1.containsAll(al4);
        
//      "abc".equals(new Person("ahaha",20));比较的是地址,都属于Object类型
    }

//  ?:啥类型不知道,就用这个  如:containsAll(),removeAll()等
    
    public static void printCollection(Collection al){
        Iterator it = al.iterator();
        
        while(it.hasNext()){
            
            System.out.println(it.next().toString());
        }
    }
总结:

集合的一些技巧:

需要唯一吗?
需要:Set
需要制定顺序:
需要:TreeSet
不需要:HashSet
但是想要一个存储一致的顺序(有序):LinkedHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList

如何记录每一个容器的结构和所属体系?
看名字!

List
|--ArrayList
|--LinkedList

Set
|--HashSet
|--TreeSet

后缀名就是该集合的所属体系。
前缀名就是该集合的数据结构。

array:就i要想到数组,查询快,有角标。
link:就i要想到链表,增删快,想到add get remove first last的方法。
hash:就i要想到哈希表,唯一性,元素需要覆盖hashcode和equals。
tree:就i要想到二叉树,排序,两个接口Comparable,Comparator。

而且通常这些常用的集合容器都是不同步的。

你可能感兴趣的:(java笔记--Collection集合框架三)