【Java】【基礎篇】day15:集合(TreeSet)和泛型

前言

本期任務:畢向東老師Java視頻教程學習筆記(共計25天)


代碼

import java.util.*;

/*
Set:無序,不可以重複元素。
	|--HashSet:數據結構是哈希表。線程是非同步的。
				保證元素唯一性的原理:判斷元素的hashCode值是否相同。
				如果相同,還會繼續判斷元素的equals方法,是否爲true。

	|--TreeSet:可以對Set集合中的元素進行排序。
				底層數據結構是二叉樹。
				保證元素唯一性的依據:
				compareTo方法return 0.

				TreeSet排序的第一種方式:讓元素自身具備比較性。
				元素需要實現Comparable接口,覆蓋compareTo方法。
				也種方式也成爲元素的自然順序,或者叫做默認順序。

				TreeSet的第二種排序方式。
				當元素自身不具備比較性時,或者具備的比較性不是所需要的。
				這時就需要讓集合自身具備比較性。
				在集合初始化時,就有了比較方式。








需求:
往TreeSet集合中存儲自定義對象學生。
想按照學生的年齡進行排序。


記住,排序時,當主要條件相同時,一定判斷一下次要條件。


*/

// 實現Comparable接口,自行編寫compareTo函數,使得學生類對象具備比較性
class Student implements Comparable {
    private String name;
    private int age;

    Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public int compareTo(Object obj) {
        if (!(obj instanceof Student))
            throw new RuntimeException("不是學生對象");

        Student s = (Student) obj;
//        System.out.println(s.getName()+"......"+s.getAge());

        if (age > s.age)
            return 1;

        if (age == s.age)
            return s.name.compareTo(name);

        return -1;

    }

}


public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet ts = new TreeSet();

        ts.add(new Student("張三", 10));
        ts.add(new Student("張三", 10));
        ts.add(new Student("張三", 11));
        ts.add(new Student("李四", 20));
        ts.add(new Student("王五", 15));

        Iterator it = ts.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s.getName() + "......" + s.getAge());
        }
    }
}
import java.util.*;

/*
當元素自身不具備比較性,或者具備的比較性不是所需要的。
這時需要讓容器自身具備比較性。
定義了比較器,將比較器對象作爲參數傳遞給TreeSet集合的構造函數。

當兩種排序都存在時,以比較器爲主。

定義一個類,實現Comparator接口,覆蓋compare方法。


*/


class Student2 {
    private String name;
    private int age;

    Student2(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

}

// 定義一個類,實現Comparator接口,覆蓋compare方法。
class MyCompare implements Comparator {
    public int compare(Object obj1, Object obj2) {
        Student2 s1 = (Student2) obj1;
        Student2 s2 = (Student2) obj2;

//        if (s1.getAge() > s2.getAge())
//            return 1;
//
//        if (s1.getAge() == s2.getAge())
//            return s1.getName().compareTo(s2.getName());
//
//        return -1;

        // 優化
        int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        if (num == 0) {
            return s1.getName().compareTo(s2.getName());
        }
        return num;

    }

}


public class TreeSetDemo2 {
    public static void main(String[] args) {
        TreeSet ts = new TreeSet(new MyCompare());

        ts.add(new Student2("張三", 10));
        ts.add(new Student2("張三", 10));
        ts.add(new Student2("張三", 11));
        ts.add(new Student2("李四", 20));
        ts.add(new Student2("王五", 15));

        Iterator it = ts.iterator();
        while (it.hasNext()) {
            Student2 s = (Student2) it.next();
            System.out.println(s.getName() + "......" + s.getAge());
        }
    }
}
/*
練習:按照字符串長度排序。

字符串本身具備比較性。但是它的比較方式不是所需要的。

這時就只能使用比較器。


需求:按照長度進行排序

思路:新建一個類,實現Comparator接口,覆蓋compare方法



*/

import java.util.*;


class LenComparator implements Comparator {
    public int compare(Object obj1, Object obj2) {
        String s1 = (String) obj1;
        String s2 = (String) obj2;

        int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
        if (num == 0) {
            return s1.compareTo(s2);
        }

        return num;
    }
}


public class TreeSetTest {

    public static void main(String[] args) {
        TreeSet ts = new TreeSet(new LenComparator());

        ts.add("jdkaflskdijf");
        ts.add("asdfa");
        ts.add("gasdf");
        ts.add("dafgds");
        ts.add("sadjfl;dj");

        Iterator it = ts.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

    }
}
/*
"90 -7 0 18 2 45 4"

將字符串中的數值進行排序。使用TreeSet完成。

思路
1,將字符串切割。
2,可以將這些對象存入TreeSet集合。因爲TreeSet自身具備排序功能。


*/

import java.util.TreeSet;

public class TreeSetTest2 {
    public static void main(String[] args) {
        String str = "90 -7 0 18 2 45 4";
        String[] arr = str.split(" ");

        TreeSet ts = new TreeSet();
        for (int x = 0; x < arr.length; x++) {
            ts.add(new Integer(arr[x]));
        }

        System.out.println(ts);

    }
}
import java.util.*;

/*
泛型:JDK1.5版本以後出現新特性。用於解決安全問題,是一個類型安全機制。

好處
1.將運行時期出現問題ClassCastException,轉移到了編譯時期。,
	方便於程序員解決問題。讓運行時問題減少,安全。,

2,避免了強制轉換麻煩。


泛型格式:通過<>來定義要操作的引用數據類型。

在使用java提供的對象時,什麼時候寫泛型呢?

通常在集合框架中很常見,
只要見到<>就要定義泛型。

其實<> 就是用來接收類型的。

當使用集合時,將集合中要存儲的數據類型作爲參數傳遞到<>中即可。





*/

public class GenericDemo {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>();

        al.add("flkads;l");
        al.add("dfajdslk;l");

        System.out.println(al);

        Iterator<String> it = al.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

    }
}
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class GenericDemo2 {
    public static void main(String[] args) {
        TreeSet<String> ts = new TreeSet<String>(new LenComparator2());

        ts.add("dakfhjl");
        ts.add("dafdfasdf");
        ts.add("daffadsf a");

        Iterator<String> it = ts.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }


    }
}

class LenComparator2 implements Comparator<String> {
    public int compare(String o1, String o2) {
        int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
        if (num == 0) {
            return o1.compareTo(o2);
        }
        return num;
    }
}

/*
什麼時候定義泛型類?
當類中要操作的引用數據類型不確定的時候,
早期定義Object來完成擴展。
現在定義泛型來完成擴展。

注:工具類本質上就是針對類對象進行特殊操作
*/

// 泛型前的做法
class Tool {
    private Object obj;

    public void setObject(Object obj) {
        this.obj = obj;
    }

    public Object getObject() {
        return obj;
    }
}

// 泛型做法

class Utils<Q> {
    private Q q;

    public void setObject(Q q) {
        this.q = q;
    }

    public Q getObject() {
        return q;
    }
}

class Worker{

}
class Student1{

}

public class GenericDemo3 {
    public static void main(String[] args) {
        Utils<Student1> u1 = new Utils<Student1>();
        u1.setObject(new Student1());
        System.out.println(u1.getObject());

        Utils<Worker> u2 = new Utils<Worker>();
        u2.setObject(new Worker());
        System.out.println(u2.getObject());

    }
}
//泛型類定義的泛型,在整個類中有效。如果被方法使用,
//那麼泛型類的對象明確要操作的具體類型後,所有要操作的類型就已經固定了。
//
//爲了讓不同方法可以操作不同類型,而且類型還不確定。
//那麼可以將泛型定義在方法上。


/*
特殊之處:
靜態方法不可以訪問類上定義的泛型。
如果靜態方法操作的應用數據類型不確定,可以將泛型定義在方法上。

*/

class Demo<T> {
    public void show(T t) {
        System.out.println("show: " + t);
    }

    public <Q> void print(Q q) {
        System.out.println("print: " + q);
    }

    public static <W> void method(W w) {
        System.out.println("method: " + w);
    }
}


public class GenericDemo4 {
    public static void main(String[] args) {
        Demo<String> d = new Demo<String>();
        d.show("hahaha");

        d.print("xixi");
        d.print(123);

        Demo.method("lalala");
        Demo.method(456);
    }
}
//泛型定義在接口上。

interface Inter<T>{
    void show(T t);
}

class InterImpl<T> implements Inter<T>{
    public void show(T t){
        System.out.println("show: "+t);
    }
}


public class GenericDemo5 {
    public static void main(String[] args) {
        InterImpl<String> iis = new InterImpl<String>();
        iis.show("abcd");

        InterImpl<Integer> iii = new InterImpl<Integer>();
        iii.show(123);
    }
}
import java.util.*;

/*
? 通配符。也可以理解爲佔位符。
泛型的限定;
? extends E: 可以接收E類型或者E的子類型。上限。
? super E: 可以接收E類型或者E的父類型。下限

*/

class Person {
    private String name;

    Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

class Student3 extends Person {
    Student3(String name) {
        super(name);
    }
}


public class GenericDemo6 {
    public static void main(String[] args) {

        ArrayList<Person> al = new ArrayList<Person>();
        al.add(new Person("張三"));
        al.add(new Person("張三"));
        al.add(new Person("李四"));
        al.add(new Person("王五"));
        printColl(al);


        ArrayList<Student3> al1 = new ArrayList<Student3>();
        al1.add(new Student3("張三1"));
        al1.add(new Student3("張三1"));
        al1.add(new Student3("李四1"));
        al1.add(new Student3("王五1"));
        printColl(al1);


    }

    // 泛型限制,集合的元素只能是Person及其子類
    public static void printColl(Collection<? extends Person> al) {
        Iterator<? extends Person> it = al.iterator();

        while (it.hasNext()) {
            System.out.println(it.next().getName());
        }

    }


}
/*
需求:
1. 類關係:
    |--Person
        |-- Worker
        |-- Student
2. 功能:生成一個適用於Person、Worker和Student的比較器, 此時只用指定Person泛型,細品
3. 使用TreeSet存放Person、Worker、Student三個類類對象
*/

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

class Person01 {
    private int age;
    private String name;

    Person01(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

}


class Student01 extends Person01 {
    Student01(String name, int age) {
        super(name, age);
    }
}

class Worker01 extends Person01 {
    Worker01(String name, int age) {
        super(name, age);
    }
}


class MyComp implements Comparator<Person01> {
    public int compare(Person01 p1, Person01 p2) {
        int num = ((Integer) p1.getAge()).compareTo((Integer) p2.getAge());
        if (num == 0) {
            return p1.getName().compareTo(p2.getName());
        }
        return num;
    }
}


class GenericDemo7 {
    public static void main(String[] args) {

        TreeSet<Person01> ts1 = new TreeSet<Person01>(new MyComp());
        ts1.add(new Person01("張三", 10));
        ts1.add(new Person01("張三", 10));
        ts1.add(new Person01("李四", 10));
        ts1.add(new Person01("王五", 11));
//        System.out.println(ts1);
        show(ts1);

        TreeSet<Student01> ts2 = new TreeSet<Student01>(new MyComp());
        ts2.add(new Student01("張三", 10));
        ts2.add(new Student01("張三", 10));
        ts2.add(new Student01("李四", 10));
        ts2.add(new Student01("王五", 11));
//        System.out.println(ts2);
        show(ts2);

        TreeSet<Worker01> ts3 = new TreeSet<Worker01>(new MyComp());
        ts3.add(new Worker01("張三", 10));
        ts3.add(new Worker01("張三", 10));
        ts3.add(new Worker01("李四", 10));
        ts3.add(new Worker01("王五", 11));
//        System.out.println(ts3);
        show(ts3);

    }

    public static void show(TreeSet<? extends Person01> ts) {
        Iterator<? extends Person01> it = ts.iterator();
        while (it.hasNext()) {
            Person01 p = (Person01) it.next();
            System.out.println(p.getAge() + "......" + p.getName());
        }
        System.out.println();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章