Day 15 集合框架01 TreeSet02 TreeSet存儲自定義對象03 二叉樹04 實現Comparator方式排序05 TreeSet練習06 泛型概述07 泛型使用08 泛型類09 泛型方法10 靜態方法泛型11 泛型介面12 泛型限定13 泛型限定2 01 TreeSet |--Se ...
Day 15 集合框架
01 TreeSet
02 TreeSet存儲自定義對象
03 二叉樹
04 實現Comparator方式排序
05 TreeSet練習
06 泛型概述
07 泛型使用
08 泛型類
09 泛型方法
10 靜態方法泛型
11 泛型介面
12 泛型限定
13 泛型限定2
01 TreeSet
|--Set
|--HashSet
|--TreeSet 可以對集合中的元素進行排序
1 import java.util.*;
2 class TreeSetTest
3 {
4 public static void main(String[] args)
5 {
6 TreeSet ts=new TreeSet();
7 ts.add("asd");
8 ts.add("sdfff");
9 ts.add("abc");
10 ts.add("Das");
11
12 Iterator it=ts.iterator();
13 while(it.hasNext())
14 {
15 System.out.println(it.next());
16 }
17
18
19 }
20 }
輸出是:(按照ASCII碼的順序排序)
Das abc asd sdfff(實際有換行)
02 TreeSet存儲自定義對象
|--Set
|--HashSet
|--TreeSet 可以對集合中的元素進行排序
需求:向TreeSet集合中存貯自定義對象學生
想要根據學生的年齡大小排序。
java中只有實現Comparable介面的類的對象才是可比較的,TreeSet才能對其排序。
註意,排序時,當主要因素相同時,就比較次要因素。
1 import java.util.*;
2 class TreeSetTest2
3 {
4 public static void main(String[] args)
5 {
6 TreeSet ts=new TreeSet();
7 ts.add(new Student("wangwu01",12));
8 ts.add(new Student("wangwu02",44));
9 ts.add(new Student("wangwu03",16));
10 ts.add(new Student("wangwu05",52));
11 ts.add(new Student("wangwu07",22));
12 ts.add(new Student("wangwu08",22));
13
14
15 Iterator it=ts.iterator();
16 while(it.hasNext())
17 {
18 Student stu=(Student)it.next();
19 System.out.println(stu.getName()+"::"+stu.getAge());
20 }
21
22
23 }
24 }
25 class Student implements Comparable
26 {
27 private String name;
28 private int age;
29 public Student(String name,int age)
30 {
31 this.name=name;
32 this.age=age;
33 }
34 public String getName(){return name;}
35 public int getAge(){return age;}
36
37 public int compareTo(Object obj)
38 {
39 //用compareTo方法比較後,如果return 0,就視為是相同的對象,不會重覆存入
40 //所以,要註意,主要因素相同時,還要比較次要因素才行
41 if(!(obj instanceof Student))
42 throw new RuntimeException("不是學生類!");
43 Student stu=(Student)obj;
44 if(this.age>stu.getAge())
45 return 1;
46 if(this.age==stu.getAge())
47 //String類型也實現了Comparable介面
48 return this.name.compareTo(stu.getName());
49 return -1;
50 }
51 }
03 二叉樹
|--TreeSet 可以對集合中的元素進行排序
底層的數據結構是二叉樹
保證元素唯一性的依據:
compareTo方法 return 0
二叉排序樹:比根元素小的元素作為左孩子節點,比根元素大的元素作為右孩子結點。
作用:減少比較次數,提高排序效率。
04 實現Comparator方式排序
TreeSet排序的第一種方式:讓元素自身具備比較性,
元素需要實現Comparable介面,覆蓋compareTo方法。
這種方式也成為元素的自然順序,或者預設順序。
TreeSet的第二種排序方式:
當元素自身不具備比較性時,或者具備的比較性不是所需要的時候,
這是就需要讓集合自身具備比較性。
定義了比較器,將比較器對象作為參宿傳遞給TreeSet集合的構造函數。
當兩種排序都存在時,以比較器為主。
比較器的定義:定義一個類,實現Comparator介面,覆蓋compare方法。
寫項目一定要留有介面,以便以後擴展其他功能。
新需求:按照學生的姓名排序。
分析:由於元素自身的比較性是按照年齡排序,不是我們所需要的。
所以要使用TreeSet第二種比較方式,定義一個比較器。
代碼如下:(Student類省略)
1 import java.util.*;
2 class TreeSetTest3
3 {
4 public static void main(String[] args)
5 {
6 TreeSet ts=new TreeSet(new myCompare());
7 ts.add(new Student("wangwu01",12));
8 ts.add(new Student("wangwu02",44));
9 ts.add(new Student("wangwu05",16));
10 ts.add(new Student("wangwu05",52));
11 ts.add(new Student("wangwu07",22));
12 ts.add(new Student("wangwu07",22));
13
14
15 Iterator it=ts.iterator();
16 while(it.hasNext())
17 {
18 Student stu=(Student)it.next();
19 System.out.println(stu.getName()+"::"+stu.getAge());
20 }
21
22
23 }
24 }
25 class myCompare implements Comparator
26 {
27 public int compare(Object o1,Object o2)
28 {
29 if(!(o1 instanceof Student && o2 instanceof Student))
30 throw new RuntimeException("有參數不是學生類!");
31 Student s1=(Student)o1;
32 Student s2=(Student)o2;
33
34 int num=s1.getName().compareTo(s2.getName());
35 //如果按姓名排是相同的,就要繼續比較其年齡
36 if(num==0)
37 {
38 return (new Integer(s1.getAge())).compareTo(s2.getAge());//return (s1.getAge()-s2.getAge());
39 }
40 return num;
41 }
42 }
05 TreeSet練習
本練習中比較器也可以定義成匿名內部類。
1 /*
2 練習:按照字元串長度排序。
3 分析:字元串的自然排序不符合需求,所以使用TreeSet第二中排序方法,定義比較器
4 */
5 import java.util.*;
6 class TreeSetTest4
7 {
8 public static void main(String[] args)
9 {
10 TreeSet ts=new TreeSet(new StrLenComparator() );
11 ts.add("qwe");
12 ts.add("qde");
13
14 ts.add("z");
15 ts.add("cv");
16 ts.add("wdsea");
17
18 Iterator it=ts.iterator();
19 while(it.hasNext())
20 {
21 System.out.println(it.next());
22 }
23 }
24 }
25 class StrLenComparator implements Comparator
26 {
27 public int compare(Object o1,Object o2)
28 {
29 if(!(o1 instanceof String && o2 instanceof String))
30 throw new RuntimeException("有對象不是字元串類型!");
31 String s1=(String)o1;
32 String s2=(String)o2;
33
34 int num=(new Integer(s1.length())).compareTo(s2.length());
35 //如果字元串長度相同,再比較其內容
36 if(num==0)
37 return s1.compareTo(s2);
38 return num;
39
40 }
41 }
06 泛型概述
泛型:JDK 1.5版本以後出現的新特性,用於解決安全問題,是一個安全機制。
(升級的原因:高效,簡化,安全)
優點:
1.將運行時期出現的問題ClassCastException,轉移到了編譯時期,
便於程式員解決問題,使運行時的問題減少,更加安全。
2.避免了強制轉換的麻煩。
1 import java.util.*;
2 class GenericDemo
3 {
4 public static void main(String[] args)
5 {
6 //在創建集合時,就為集合中的元素指明類型,
7 //一旦存入錯誤的類型,編譯時就會報錯
8 ArrayList<String> al=new ArrayList<String>();
9
10 al.add("asss01");
11 al.add("edcc");
12 al.add("edscs");
13
14 //為迭代器指明類型
15 //就不用強制轉換了
16 Iterator<String> it=al.iterator();
17 while(it.hasNext())
18 {
19 String s=it.next();
20 System.out.println(s+":"+s.length());
21 }
22 }
23 }
07 泛型使用
泛型格式:通過<>來定義要操作的引用數據類型
在使用java提供的對象時,什麼時候寫泛型呢?
通常在集合框架中很常見。只要見到<>就要定義泛型。
其實<>就是用來接受類型的。
當使用集合時,將集合中要存儲的數據類型作為參數傳遞到<>中即可。
1 import java.util.*;
2 class GenericDemo2
3 {
4 public static void main(String[] args)
5 {
6 TreeSet<String> ts=new TreeSet<String>(new LenStrComparator());
7 ts.add("assd");
8 ts.add("df");
9 ts.add("er");
10 ts.add("dfg");
11
12 Iterator<String> it=ts.iterator();
13 while(it.hasNext())
14 {
15 String s=it.next();
16 System.out.println(s);
17 }
18
19 }
20 }
21 class LenStrComparator implements Comparator<String>//添加泛型,避免了compare方法中強轉的麻煩
22 {
23 public int compare(String s1,String s2)
24 {
25 //如果想按字元串長度降序輸出,則調換s1,s2位置。
26 int num=(new Integer(s1.length())).compareTo(new Integer(s2.length()));
27 if(num==0)
28 return s1.compareTo(s2);
29 return num;
30 }
31 }
08 泛型類
泛型類:
什麼時候定義泛型類?
當類中要操作的引用數據類型不確定時,
早期定義Object來完成擴展
現在定義泛型來完成。
1 import java.util.*;
2 class Student
3 {
4 }
5 class Worker
6 {
7 }
8 //泛型出現前的用法
9
10 class Tool
11 {
12 private Object obj;
13 public void setObject(Object obj)
14 {
15 this.obj=obj;
16 }
17 public Object getObject()
18 {return obj;}
19 }
20 //使用泛型的做法
21 class Utils<T>
22 {
23 private T t;
24 public void setObject(T t)
25 {
26 this.t=t;
27 }
28 public T getObject()
29 {
30 return t;
31 }
32 }
33 class GenericDemo3
34 {
35
36 public static void main(String[] args)
37 {
38 Utils<Worker> u=new Utils<Worker>();
39 Worker w=u.getObject();//不再需要強轉了
40
41 /*Tool t=new Tool();
42 t.setObject(new Student());
43 Worker w=(Worker)t.getObject();
44 */
45 }
46 }
09 泛型方法
泛型類定義的泛型,在整個類中有效,如果被方法使用,
那麼泛型類的對象明確要操作的數據類型後,所有要操作的類型就已經固定了。
為了讓不同的方法可以操作不同的類型,而且類型不確定,
那麼可以將泛型定義在方法上。
1 import java.util.*;
2 class Demo
3 {
4 public <T> void show(T t)
5 {
6 System.out.println("show:"+t);
7 }
8 public <Q> void print(Q q)
9 {
10 System.out.println("print:"+q);
11 }
12 }
13 class GenericDemo4
14 {
15 public static void main(String[] args)
16 {
17 Demo d=new Demo();
18 d.show(4);//裝箱,拆箱
19 d.print("hahaha");
20
21 }
22 }
10 靜態方法泛型
特殊:
靜態方法不可以使用定義在類上的泛型(無法從靜態上下文中引用非靜態)
如果靜態方法操作的方法不確定,可以把泛型定義在方法上。
註意泛型在方法頭部中的位置,在修飾符後,返回值類型之前,例如 public static <T> void method()。
11 泛型介面
1 /*
2 泛型定義在介面上
3 */
4 import java.util.*;
5 interface Inter<T>
6 {
7 public void show(T t);
8 }
9 class InterImp<T> implements Inter<T>
10 {
11 public void show(T t)
12 {
13 System.out.println(t);
14 }
15 }
16 class GenericDemo5
17 {
18 public static void main(String[] args)
19 {
20 InterImp<Integer> i=new InterImp<Integer>();
21 i.show(5);
22 }
23 }
12 泛型限定
? 通配符,也可以理解為占位符
應用1:
1 import java.util.*;
2 class GenericDemo6
3 {
4 public static void main(String[] args)
5 {
6 ArrayList<String> al=new ArrayList<String>();
7 al.add("abc1");
8 al.add("abc2");
9 al.add("abc3");
10 al.add("abc4");
11
12 ArrayList<Integer> al1=new ArrayList<Integer>();
13 al1.add(2);
14 al1.add(5);
15 al1.add(6);
16
17 printColl(al);
18 printColl(al1);
19
20
21 }
22 public static void printColl(ArrayList<?> al)//使用通配符,可以操作不同類型的對象。也可以用T
23 {
24 Iterator<?> it=al.iterator();
25 while(it.hasNext())
26 {
27 System.out.println(it.next());
28 }
29 }
30 }
應用2:
泛型的限定
? extends E:可以接受E類型或者E類型的子類,上限。
? super E:可以接受E類型或者E類型的父類,下限。
用到? extends E中的地方:
Collection介面中 :boolean addAll(Collection<? extends e> c)
用到? super E中的地方:
TreeSet類中 :TreeSet(Comparator<?super e> comparator)
1 import java.util.*;
2 class GenericDemo6
3 {
4 public static void main(String[] args)
5 {
6 ArrayList<Person> al=new ArrayList<Person>();
7 al.add(new Person("abc01"));
8 al.add(new Person("abc02"));
9 al.add(new Person("abc03"));
10 al.add(new Person("abc04"));
11
12 //printColl(al);
13
14 ArrayList<Student> al1=new ArrayList<Student>();
15 al1.add(new Student("abc--01"));
16 al1.add(new Student("abc--02"));
17 al1.add(new Student("abc--03"));
18 al1.add(new Student("abc--04"));
19 printColl(al1);
20 //ArrayList<Person> al=new ArrayList<Student>();Error!
21 //Person p=new Student();正確的,多態
22 //ArrayList<Student> al=new ArrayList<Person>(); 也是錯誤的! 要一致
23
24 }
25 public static void printColl(ArrayList<? extends Person> al)
26 {
27 Iterator<? extends Person> it=al.iterator();
28 while(it.hasNext())
29 {
30 System.out.println(it.next().getName());
31 }
32 }
33 }
34 class Person
35 {
36 private String name;
37 public Person(String name)
38 {
39 this.name=name;
40 }
41 public String getName()
42 {
43 return name;
44 }
45 }
46 class Student extends Person implements Comparable<Person>//<? super E>
47 {
48 public Student(String name)
49 {
50 super(name);
51 }
52 public int compareTo(Person p)
53 {
54 return (this.getName()).compareTo(p.getName());
55 }
56 }
13 泛型限定2
泛型限定是擴展用的。
? super E的例子
TreeSet(Comparator<? super E> comparator)一個類父類的比較器類也可用作這個類構造方法的參數
這個例子中Student類和Worker類就都用了它們父類Person的比較器Comp類
1 import java.util.*;
2 class GenericDemo7
3 {
4 public static void main(String[] args)
5 {
6 TreeSet<Student> ts1=new TreeSet<Student>(new Comp());
7 ts1.add(new Student("qaz1"));
8 ts1.add(new Student("qaz3"));
9 ts1.add(new Student("qaz6"));
10
11 Iterator<Student> it=ts1.iterator();
12 while(it.hasNext())
13 {
14 System.out.println(it.next().getName());
15 }
16
17 TreeSet<Worker> ts2=new TreeSet<Worker>(new Comp());
18 ts2.add(new Worker("w--qaz1"));
19 ts2.add(new Worker("w--qaz3"));
20 ts2.add(new Worker("w--qaz6"));
21
22 Iterator<Worker> it2=ts2.iterator();
23 while(it2.hasNext())
24 {
25 System.out.println(it2.next().getName());
26 }
27 }
28
29 }
30 class Person
31 {
32 private String name;
33 public Person(String name)
34 {
35 this.name=name;
36 }
37 public String getName()
38 {
39