黑馬程序員- 集合框架

------- android培訓java培訓、期待與您交流! ----------

1,集合類

    爲什麼出現集合類?

     面嚮對象語言對實物的體現都是以對象的形式,所以爲了方便對多個對象的操作,就對對象進行存儲,集合就是存儲最常用的一種方式。

      集合和集合類同時容器,有何不同?

    數組雖然也可以存儲對象,但長度是固定的,集合長度是可變的

   數組中可以存儲基本數據類型,集合只能存儲對象。

   集合類的特點

       集合只用於存儲對象,集合的長度是可變的,集合可以存儲不同類型的對象。

2,集合的學習體系:

    ----  |Colleciton 描述所有接口的共性

        ------|List可以有重複元素的集合

        ------|Set 不能有重複元素的集合

3,Collection 常用方法

    1增加:

          add();將指定的對象存儲到集合容器中

          addAll() 將指定集合中的元素添加到調用方法集合中

     2,刪除

           remove()將指定集合元素添加到調用該方法的集合中。

           removeAll()將指定集合中的元素刪除

     3,修改:

         clear()清空集合中的所有元素

      4,判斷

          isEmpty() 判斷集合是否爲空

          contains()判斷集合中是否包含指定對象 使用equals()判斷兩個對象是否相等

          containsAll(0判斷集合中是否包含指定集合 使用equals()判斷兩個對象是否相等。

      5,獲取

          size()返回集合容器的大小

       6,查看集合裏面的所有元素轉換方法:

           toArray()返回包含collection中所有元素的數組

       7,Iterable迭代器 該類主要用來便利集合對象,該類描述了遍歷集合的常用迭代方法。

            1,hashNext()如果有元素可以迭代,就返回true;

            2,next()返回下一個元素。如果沒有下一個元素,調用元素會拋出NoSuchElementExcepton

            3,remover()從迭代器指向的集合中移除迭代器返回的最後一個元素

            4,迭代器 遊戲或指針,其實就是調用了ArrayList.get() index++;

import java.util.ArrayList;

public class Test1 {
	public static void main(String[] args) {
		ArrayList a1 = new ArrayList();
		// 添加元素
		a1.add("java01");// add(Object obj);
		a1.add("java02");
		a1.add("java03");
		sop(a1);

		a1.remove("java02");// 刪除元素
		a1.clear();// 清除元素
		sop("java03是否存在" + a1.contains("java01"));
		sop("集合是否爲空?" + a1.isEmpty());
		// 獲取長度
		sop("size" + a1.size());
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}
import java.util.ArrayList;
import java.util.Iterator;

/*
 * 什麼是迭代器
 * 其實就是集合的取出元素的方式。
 */

public class Test2 {
	public static void main(String[] args) {
		method_get();
	}

	public static void method_get() {
		ArrayList a1 = new ArrayList();
		// 添加元素
		a1.add("java01");// add(Object obj);
		a1.add("java02");
		a1.add("java03");
		Iterator it = a1.iterator();// 獲取迭代器,用於取出集合中的元素
		while (it.hasNext()) {
			sop(it.next());
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}



 

 4,List

     1,獲取

          1,get(int index);

               注意:IndexOutOfBoundsExcepton;

            2,修改

                set(int index,E element);

            3,查找:

                   int indexOf(Object);//找不到返回-1;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
 * Collection 
 *     |--List:元素是有序的,元素可以重複,因爲該集合體繫有索引
 *     |--Set :元素無序,元素不可以重複
 *   List
 *   本身也是一個抽取出來的接口
 *   特有方法:凡是可以操作角標的方法都是該體系特有的方法
 *    增
 *      add(index,element);
 *      addAll(index,Collection);
 *    刪
 *       remove(index);
 *    改
 *     set(index,elemet);
 *    查
 *       get(index);
 *       subList(from,to);
 *       listIterator();
 */
public class Test3 {
	public static void sop(Object obj) {
		System.out.println(obj);
	}

	public static void main(String[] args) {
		ArrayList a1 = new ArrayList();
		a1.add("java01");
		a1.add("java02");
		a1.add("java03");
		sop("源集合是" + a1);
		a1.add(1, "java09");// 添加指定位置
		a1.remove(2);// 刪除指定位置的元素
		// 修改元素
		a1.set(2, "java07");
		// 通過角標獲取元素
		sop("get(1):" + a1.get(1));
		// 獲取所有元素
		for (int x = 0; x < a1.size(); x++) {
			System.out.println("a1" + a1.get(x));
		}
		Iterator it=a1.iterator();
		while(it.hasNext()){
			sop("next:"+it.next());
		}
		sop("index"+a1.indexOf("java02"));
		List sub=a1.subList(1, 3);//包含1不包含3
		sop("sub"+sub);
	}
}


 刪除list集合重複的值。

 

import java.util.ArrayList;
public class Test{
 public static void main(String[] args) {
  ArrayList list = new ArrayList();
  //list.add("abc");
  list.add("adb");
  list.add("abc");
  list.add("abc");
  list.add("adb");
  list.add("abc");
  System.out.println(list.size());
  //int size = list.size();
  for (int x = 0; x < list.size(); x++){//循環
   String str = (String)list.get(x);
   if (str.equals("abc")) {//判斷條件
    list.remove(x);
      // list.remove(0);
       System.out.println("--還剩下"+list.size()+".."+x);
       x=-1;//集合的長度在不斷的變化,所以這裏要是x=-1;
   }
  }
  System.out.println(list);
  System.out.println(list.size());
 }
}
 

5,ArrayList,LinkedList比較

        2, ArrayList 實現List接口

        3,LinkedList

             1,查找元素慢,出入和刪除快。

         4,ArrayList和LinkedList的存儲查找的優點和缺點

            1,ArrayList是採用動態數組來存儲元素的,它允許直接下標號直接查找對應的元素。

                     但是,插入元素要涉及數組元素移動及內存的操作。總結:查找速度快,插入操作忙。

            2,LindedList 是採用雙向鏈表示實現存儲,按序號索引數據需要進行前向或後向便利

                    但是插入數據的時,只需要記錄本項前後項即可,所以插入速度快。

import java.util.LinkedList;

public class Test4 {
	public static void main(String[] args) {
		LinkedList link = new LinkedList();
		link.addFirst("java01");// linklist特有方法
		link.addFirst("java02");
		link.addFirst("java03");
		link.addFirst("java04");
		link.addLast("java05");
		sop(link);
		sop(link.getFirst());// 不刪除獲取
		sop(link.getLast());
		sop(link.remove());// 獲取並刪除
		sop(link.size());
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}

}


6,Set

   Set:元素是無序(存入和取出的順序不一定一致),元素不可以重複

   Set:集合的功能和Collection是一致的。

      1,問題:有一批數據要存儲,要求存儲這批數據不能出現重複數據,ArrayList,LinkedList都沒法滿足需求

          解決方法:Set集合

      2,set集合特點:無序。不能有重複元素的集合

      3,HashSet:數據結構是哈希表,線程是非同步的

         哈希表是按照哈希值來存儲的

          不是同一對象,但是地址值是一樣的,這個時候他會在該地址值下順延。

            保證元素唯一性的原理:判斷元素的hashCode值是否相同

           如果相同,還會繼續判斷元素的equals方法,是否爲true;添加失敗就爲假。

            HashSet是如何保證元素唯一性的呢?

              是通過元素的兩個方法,hashCode和equals來完成。

              如果元素的HashCode值相同,纔會判斷euqals是否爲true,如果元素的hashscode值不同,不會調用equals.(建立一個比較有針對性的hashcode會比較高效一些)

       

import java.util.HashSet; import java.util.Iterator;

/**  * HashSet存儲自定義對象  *  * @author Administrator 網hashset存入自定義對象,姓名和年齡相同爲同一個人,重複元素  */ public class Test {  public static void main(String[] args) {   HashSet hs = new HashSet();   //添加person對象   hs.add(new Person("a1", 11));   hs.add(new Person("a2", 12));   hs.add(new Person("a3", 13));   hs.add(new Person("a2", 12));   //hs.add(new Person("a4", 14));   Iterator it = hs.iterator();//迭代器對象   //遍歷   while (it.hasNext()) {    Person p = (Person) it.next();//強制類型轉換    sop(p.getName()+"::"+p.getAge());   }  }    /**     * 打印方法     * @param obj     */  public static void sop(Object obj) {   System.out.println(obj);  } }  /**   * person類,名字年齡   * @author Administrator   *   */ class Person {  private String name;

 public String getName() {   return name;  }

 public int getAge() {   return age;  }

 private int age;

 Person(String name, int age) {   this.name = name;   this.age = age;  }     //重寫equals方法  public boolean equals(Object obj) {   if (!(obj instanceof Person)) {    return false;   }   Person p = (Person) obj;   return this.name.equals(p.name) && this.age == p.age;  } }

以上打印結果爲:

     a2::12
     a1::11
     a2::12  
     a3::13

equals沒有被調用。因爲比較先看地址。new 出來的,都有自己獨立的hashcode,有自己的位置存儲,都存進去了,不用再讀equals方法了。

現在要覆蓋Person 的hashcode方法,建立Person對象自己的哈希值。怎麼建立哈希值呢?你的判斷條件是什麼,依據條件來生成哈希值,這裏按照姓名年齡判斷是不是同一個元素,那就依據這個條件判斷哈希值。

  

import java.util.HashSet;
import java.util.Iterator;

/**
 * HashSet存儲自定義對象
 * 
 * @author Administrator 網hashset存入自定義對象,姓名和年齡相同爲同一個人,重複元素
 */
public class Test2 {
	public static void main(String[] args) {
		HashSet hs = new HashSet();
		hs.add(new Person("a1", 11));
		hs.add(new Person("a2", 12));
		hs.add(new Person("a3", 13));
		hs.add(new Person("a2", 12));
		//hs.add(new Person("a4", 14));
		Iterator it = hs.iterator();
		while (it.hasNext()) {
			Person p = (Person) it.next();
			sop(p.getName()+"::"+p.getAge());
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}

class Person {
	private String name;

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	private int age;

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
    public int hashCode(){
    	System.out.println(this.name+"....hashcode");
    	//按照條件設置hashcode
    	return name.hashCode()+this.age*39;//39沒有特殊意思,也可以是其他,容易導致hashcode相同,儘量保持哈希值的唯一
    //不科學的比較方式	return 60;
    }
	public boolean equals(Object obj) {
		if (!(obj instanceof Person)) {
			return false;
		}
		Person p = (Person) obj;
		System.out.println(this.name+".euqals.."+p.name);
		return this.name.equals(p.name) && this.age == p.age;
	}
}


 

科學的打印

a1....hashcode
a2....hashcode
a3....hashcode
a2....hashcode
a2.euqals..a2
a2::12
a3::13
a1::11

非科學打印結果爲

a1....hashcode
a2....hashcode
a2.euqals..a1
a3....hashcode
a3.euqals..a2
a3.euqals..a1
a2....hashcode
a2.euqals..a3
a2.euqals..a2
a3::13
a2::12
a1::11
HashSet判斷和刪除的依據

注意:對於判斷元素是否存在,以及刪除等操作,依賴的方法是元素的hashCode和equals方法。先判斷hashCode,hashcode如果有的話, 再判斷equals.

import java.util.HashSet; import java.util.Iterator;

/**  * HashSet存儲自定義對象  *  * @author Administrator 網hashset存入自定義對象,姓名和年齡相同爲同一個人,重複元素  */ public class Test {  public static void main(String[] args) {   HashSet hs = new HashSet();   hs.add(new Person("a1", 11));   hs.add(new Person("a2", 12));   hs.add(new Person("a3", 13));   hs.add(new Person("a2", 12));   //hs.add(new Person("a4", 14));   sop(hs.contains(new Person("a1",11)));   hs.remove(new Person("a1",11));   Iterator it = hs.iterator();   while (it.hasNext()) {//迭代器迭代    Person p = (Person) it.next();    sop(p.getName()+"::"+p.getAge());   }  }    //打印  public static void sop(Object obj) {   System.out.println(obj);  } }

class Person {  private String name;

 public String getName() {   return name;  }

 public int getAge() {   return age;  }

 private int age;

 Person(String name, int age) {   this.name = name;   this.age = age;  }  //重寫hashCode方法     public int hashCode(){      System.out.println(this.name+"....hashcode");      //按照條件設置hashcode      return name.hashCode()+this.age*39;//39沒有特殊意思,也可以是其他,容易導致hashcode相同,儘量保持哈希值的唯一     //不科學的比較方式 return 60;     }     //重寫equals方法  public boolean equals(Object obj) {   if (!(obj instanceof Person)) {    return false;//如果不是Person的實例,返回false;   }   Person p = (Person) obj;   System.out.println(this.name+".euqals.."+p.name);   return this.name.equals(p.name) && this.age == p.age;//比較年齡和名字  } }

ArrayList判斷元素是否存在,和刪除元素只依賴於equals,而hashSet依賴於hashCode和equals

     4TreeSet:可以對set集合中的元素進行排序。自然順序ASCII表

          

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

/**
 * 可以對Set集合中的元素進行排序。Ascii排序
 * 
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add("abcd");
		ts.add("abcg");
		ts.add("aaaa");
		ts.add("bca");
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());// 跟存的順序不一樣但是打印的時候有自己的順序
			// 打印結果aaaa
			// abcd
			// abcg
			// bca
		}
	}
}


 

                       底層數據結構是二叉樹

                       保證元素的唯一性的依據

                       compareTo方法return 0,返回0認爲元素相同,否則都不相同

                       排序的第一種方式:讓元素自身具備比較性,讓元素自身具備比較性。

                         元素需要實現Compaable接口,覆蓋compareTo方法,這種方式稱爲元素的自然順序,或者叫做默認順序,一被定義出來就具備比較性

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

                 存儲自定義對象

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

/**
 * 存儲之定義對象
 * 往TreeSet集合中存儲自定義對象
 * 想按照學生的年齡進行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lise007", 20));
		ts.add(new Student("lise09", 22));
		ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());

		}
	}
}

class Student {
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

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

	public String getName() {
		return name;
	}

}

類型轉換異常,學生不能不能被轉換java.lang.Comparable
Comparable接口強行對實現它的每個類的對象進行整體排序。這種排序被稱爲類的自然排序,類的compareTo方法被稱爲自然比較法。

以上例子,存儲一個對象,就沒有異常,再存就出現了異常。。TreeSet集合能排序,可是按照什麼方式排呢?學生對象不具備比較性。所以java說,你必須要讓你的元素具備比較性。TreeSet集合的要求是,往裏面存的集合必須具備比較性。怎麼具備比較性呢?

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

/**
 * 存儲之定義對象
 * 往TreeSet集合中存儲自定義對象
 * 想按照學生的年齡進行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lise007", 20));
		ts.add(new Student("lise09", 19));
	//	ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());

		}
	}
}

class Student implements Comparable {//該類接口強制讓學生具備比較性
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

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

	public String getName() {
		return name;
	}

	@Override
	public int compareTo(Object obj) {
		// TODO Auto-generated method stub
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是學生對象");
		}
		Student s=(Student)obj;
		System.out.println(this.name+"...........compareto........"+s.name);
		if(this.age>s.age){//此對象大於指定對象返回正數
		   return 1;
		}else if(this.age==s.age){
			return 0;
		}
		return -1;
	}

}

但是以上的代碼還是有問題的。如果再添加一個年齡相同的對象,則發現打印 的時候少了一個對象。當他們年齡相等的時候,compareTo返回0.
代表此對象與指定對象是相同的。就沒有存進去。在本例中,年齡相同,姓名也相同纔是同一個人。毫無疑問,判斷完年齡後,再判斷一下姓名。當主要條件相同時,要排序次要條件排。次要條件相同,那就相同了。這裏要比較字符串,字符串具備比較行爲。String 類的compareTo(String anotherString)按照字典順序比較兩個字符串。

String類,本身就已經實現了Comparable.java中的很多對象都具備比較性。

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

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

/**
 * 存儲之定義對象
 * 往TreeSet集合中存儲自定義對象
 * 想按照學生的年齡進行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lise007", 20));
		ts.add(new Student("lise09", 19));
		ts.add(new Student("lise10", 19));
	//	ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());

		}
	}
}

class Student implements Comparable {//該類接口強制讓學生具備比較性
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

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

	public String getName() {
		return name;
	}

	@Override
	public int compareTo(Object obj) {
		// TODO Auto-generated method stub
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是學生對象");
		}
		Student s=(Student)obj;
		System.out.println(this.name+"...........compareto........"+s.name);
		if(this.age>s.age){//此對象大於指定對象返回正數
		   return 1;
		}else if(this.age==s.age){
	            return this.name.compareTo(s.name);
		}
		return -1;
	}

}

TreeSet 排序就是互相比較,元素越多,你互相比較的次數越多,效率很低。所以爲了優化效率,TreeSet用了一種特殊的數據結構。二叉樹,減少比較次數,提高比較性能。(小於的在左邊,大於的在右邊)

如果是降序,return 的值1變爲-1,都取反。

現在讓數據怎麼存進去的怎麼取出來。怎麼做呢?

在TreeSet比較對象的時候,和compareTo 方法中的if判斷是沒有關係的。只看結果,是正是負,是0,?直接return 1就可以實現。

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

在集合初始化時,就有了比較方式。構造函數

定義比較器,將比較器對象作爲參數傳遞給TreeSet集合的構造函數。

第一種,讓元素具備比較性,第二種讓容器自身具備比較性。當兩種排序都存在時,以比較器爲主。

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

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

/**
 * 存儲之定義對象
 * 往TreeSet集合中存儲自定義對象
 * 想按照學生的年齡進行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new MyCompares());
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lisi007", 20));
		ts.add(new Student("lisi09", 19));
		ts.add(new Student("lisi10", 19));
		ts.add(new Student("lisi007", 20));
	//	ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());

		}
	}
}

class Student implements Comparable {//該類接口強制讓學生具備比較性
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

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

	public String getName() {
		return name;
	}

	@Override
	public int compareTo(Object obj) {
		// TODO Auto-generated method stub
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是學生對象");
		}
		Student s=(Student)obj;
		//System.out.println(this.name+"...........compareto........"+s.name);
		if(this.age>s.age){//此對象大於指定對象返回正數
		   return 1;
		}else if(this.age==s.age){
	            return this.name.compareTo(s.name);
		}
		return -1;
	}

}
class MyCompares implements Comparator{
 //這裏不用複寫equals方法了,因爲MyCompares繼承了Object了。已經有了equals
	@Override
	public int compare(Object o1, Object o2) {
		// TODO Auto-generated method stub
		Student s1=(Student)o1;
		Student s2=(Student)o2;
		int num= s1.getName().compareTo(s2.getName());
		if(num==0){//主要條件相同,判斷次要條件
			/*if(s1.getAge()>s2.getAge()){
				return 1;
			}
			if(s1.getAge()==s2.getAge()){
				return 0;
			}
			//return -1;*/
		return	new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}
		return num;
	
	}
	
}

以上就是排序的兩種方式。

實例:按照字符串長度進行比較

import java.util.HashSet;
import java.util.Iterator;

public class Test5 {
	public static void main(String[] args) {
		// Test5 t1=new Test5();
		// Test5 t2=new Test5();
		HashSet hs = new HashSet();
		hs.add("javao1");// 返回true
		hs.add("javao1");// 返回false;
		hs.add("javao2");
		hs.add("javao3");
		Iterator it = hs.iterator();
		while (it.hasNext()) {
			sop(it.next());
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

/*  * 按照字符串長度排序TreeSet基本應用  */ public class Test6 {  public static void main(String[] args) {   TreeSet ts = new TreeSet(new StringLengthCommparator());   ts.add("abcd");   ts.add("cc");   ts.add("z");   ts.add("hahha");   Iterator it = ts.iterator();   while (it.hasNext()) {    System.out.println(it.next());   }  } }

class StringLengthCommparator implements Comparator {

 @Override  public int compare(Object o1, Object o2) {   // TODO Auto-generated method stub   String s1 = (String) o1;   String s2 = (String) o2;   /*    * if(s1.length()>s2.length()){ return 1; }    * if(s1.length()==s2.length()){ return 0; }    */   int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));   if (num == 0) {    return s1.compareTo(s2);   }   return num;  }

}

 

|-- HashSet
       |-- 底層是哈希表,不存儲重複元素
       |-- 存儲自定義對象,需要覆蓋對象中的hashCode和equals方法,保證對象對象唯一
     |-- TreeSet
       |-- 底層是二叉樹結構,不存儲重複元素
       |-- 存儲對象,按照對象的自然順序排序
       |-- 自定義對象,必須具備比較性
         |--對象本身具備比較性,實現Comparable接口,覆蓋compareTo方法
         |--TreeSet本身具備比較性,自定義比較器,實現Comparator接口,覆蓋compare方法  

 7,泛型

        1泛型的好處:

            1,將運行時的異常提前至編譯時發生

            2,使用get獲取元素的時候無需強類型轉型,就避免了類型轉換的異常問題

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

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

通常在集合框架中很常見

只要見到<>就要定義泛型。

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

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

上面的例子可以優化

 

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

/**
 * 存儲之定義對象
 * 往TreeSet集合中存儲自定義對象
 * 想按照學生的年齡進行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet<Student> ts = new TreeSet<Student>(new MyCompares());
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lisi007", 20));
		ts.add(new Student("lisi09", 19));
		ts.add(new Student("lisi10", 19));
		ts.add(new Student("lisi007", 20));
	//	ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());

		}
	}
}

class Student implements Comparable {//該類接口強制讓學生具備比較性
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

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

	public String getName() {
		return name;
	}

	@Override
	public int compareTo(Object obj) {
		// TODO Auto-generated method stub
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是學生對象");
		}
		Student s=(Student)obj;
		//System.out.println(this.name+"...........compareto........"+s.name);
		if(this.age>s.age){//此對象大於指定對象返回正數
		   return 1;
		}else if(this.age==s.age){
	            return this.name.compareTo(s.name);
		}
		return -1;
	}

}
class MyCompares implements Comparator<Student>{//定義泛型不用轉換了。
 
	@Override
	public int compare(Student s1, Student s2) {
		// TODO Auto-generated method stub
		
		int num= s1.getName().compareTo(s2.getName());
		if(num==0){//主要條件相同,判斷次要條件
			
		return	new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}
		return num;
	
	}
	
}


 

以下是自定義泛型的示例

public class Test7 {
   public static void main(String[] args) {
	   
	  Tool<Worker> u=new Tool<Worker>();
	  u.setObject(new Worker());
	  Worker w=u.getObect();
   }
}
class Worker{
	
}
class Student{
	
}
class Tool<QQ>{
	private QQ q;
	public void setObject(QQ q){
		this.q=q;
	}
	public QQ getObect(){
		return q;
	}
}


 什麼時候定義泛型類呢?

當類中要操作的引用數據類型不確定的時候,早期定義Object來完成擴展。

現在定義泛型來完成擴展。

泛型類定義的泛型,在整個類中有效,如果被方法使用,那麼泛型類的對象明確要操作的具體類型後,所有要操作的類型就已經固定了。

爲了讓不同方法可以操作不同類型,而且類型還不確定,那麼可以就將泛型定義在方法上。

class Demo{

       public <T> void show(T t)

      {

             syso(t)

      }

}

  8,map

        --|Map接口   將鍵映射到值得對象。一個映射不能包含重複的鍵;每個鍵最多隻能映射到一個值。

              --|HashMap採用哈希表實現,所以無序

         1,常見方法

                  添加

              put(key,value);可以使用相同的key值,但是添加的value值會覆蓋前面的,返回值是前一個value。

                   //添加元素,如果出現相同的鍵,那麼後添加的值會覆蓋原有鍵對應的值。並put方法返回被覆蓋的值。

                     刪除

             remove(key)刪除關聯對象,指定key對象

             clear()清除集合對象

                   判斷

              containsValue(Object value)

              containsKey(Object key)

              isEmpty()

                     獲取

              get(Object key);

               size()

                value()

                entrySet()

                 keySet()

          2,遍歷方式

               需要分別獲取key和value Set<> keySet()返回所有對象的Set集合

          3,結構體系

                   |--Hashtable:底層是哈希表數據結構,不可以存入null鍵null值,該集合是線程同步的,用作鍵的對象,必須實現hashCode方法,和equals方法,該集合是元老級別的。效率低。

                   |--HashMap:底層是哈希表數據結構,並允許使用null鍵null值,該集合不同步的,效率高。

                   |--TreeMap:底層是二叉樹數據結構,線程不同步,,可以用於給map集合中的鍵進行排序

             和set很像,Set底層就是使用了Map集合

Map.Entry其實Entry也是一個接口,它是Map接口中的一個內部接口。Map集合內部的事物,只有有了Map集合纔能有關係,Entry直接訪問Map集合中的元素。所以定義了內部規則。

public static interface Map.Entry<k,v>;能加static的接口一定是內部接口。只有接口在成員位置上,才能加上靜態修飾符。

interface Map{

    public static interface Entry{

             public abstract Object getKey();

            public abstract Object getValue();

   }

}

class HashMap implements Map.Entry{

   public Object getKey();

   public Object getValue();

}

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class Test8 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("01", "a1");
		map.put("02", "a2");
		map.put("03", "a3");
		System.out.println("containsKey" + map.containsKey("022"));// false
		System.out.println("remove" + map.remove("02"));// 返回移除的值
		System.out.println("get:" + map.get("023"));// 判斷是否存在,返回null
		map.put("04", null);// 空可以作爲鍵存在,Hashtbale不能空
		System.out.println("get:" + map.get("04"));// 可以通過get方法的返回值來判斷一個鍵是否存在
		// 獲取map集合中所有的值
		Collection<String> coll = map.values();
		System.out.println(coll);// 無序的
		// map.put(key,value)返回這個鍵對應的原來的值,沒有返回null,存在則覆蓋原有鍵對應的值,put方法返回被覆蓋的值
		System.out.println("put:" + map.put("05", "a5"));

	}
}

keyset的示例

 取出原理:將map集合轉成set集合。在通過迭代器取出。

       
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
 * map集合的兩種取出方式
 *  1,keySet:將map中所有的鍵存入到set集合。因爲set具備迭代器
 *    所有可以迭代方式取出所有的鍵,在根據get方法獲取每一個鍵對應的值
 *   2,entrySet
 */
public class Test9 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("01", "a1");
		map.put("02", "a2");
		map.put("03", "a3");
		// 先獲取map集合的所有鍵的set集合,keyset();
		Set<String> keySet = map.keySet();
		// 有了Set集合,就可以獲取其迭代
		Iterator<String> it = keySet.iterator();
		while (it.hasNext()) {
			String key = it.next();
			// 有了鍵就可以通過map集合的get方法獲取其對應的值
			String value = map.get(key);
			System.out.println("key" + key + "value:" + value);
		}
	}
}


 entrySet示例

  

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
 * Set<Map.Entry<k,v>> entrySet:將map集合中的映射關係存入到了set集合中,
 * 而這個關係數據類型就是:Map.Entry
 */
public class Test10 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("01", "a1");
		map.put("02", "a2");
		map.put("03", "a3");
		// 將map集合中的映射關係取出,存入set集合中
		Set<Map.Entry<String, String>> entrySet = map.entrySet();
		Iterator<Map.Entry<String, String>> it = entrySet.iterator();
		while (it.hasNext()) {
			Map.Entry<String, String> me = it.next();
			String key = me.getKey();
			String valeu = me.getValue();
		}
	}
}


 

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 練習: 每一個學生都有對應的歸屬地。 學生Student 地址String 學生屬性:姓名,年齡 注意:姓名和年齡相同的視爲同一個學生。
 * 保證學生的唯一性。
 * 
 * @author Administrator
 * 
 */
public class Test5 {
	public static void main(String[] args) {
         Map<Student1,String> map=new HashMap<Student1,String>();
         map.put(new Student1("lisi1",21), "beijign");
         map.put(new Student1("lisi2",22), "shanghai");
         map.put(new Student1("lisi3",23), "nanjing");
         map.put(new Student1("lisi4",24), "wuhan");
         //第一種方式取出keySet
         Set<Student1> keyset=map.keySet();
         Iterator<Student1> it=keyset.iterator();
         while(it.hasNext()){
        	 Student1 stu=it.next();
        	 String addr=map.get(stu);
        	 System.out.println(stu+".."+addr);
         }
         //第二種取出方式:
           Set<Map.Entry<Student1, String>>  entrySet=map.entrySet();
           Iterator<Map.Entry<Student1, String>> iter=entrySet.iterator();
           while(iter.hasNext()){
        	   Map.Entry<Student1, String> me=iter.next();
        	   Student1 stu=me.getKey();
        	   String addr=me.getValue();
        	   System.out.println(stu+"..."+addr);
           }
	}
}


class Student1 implements Comparable<Student1> {
	private String name;
	private int age;
      Student1(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;
	}
	public String toString(){
		return name+":"+age;
	}
	public int hashCode(){
		return name.hashCode()+age*34;
	}
	public boolean euqals(Object obj){//不能加泛型
		if(!(obj instanceof Student)){
		//	return new RuntimeException("類型不匹配");
			throw new ClassCastException("類型不匹配");
		}
		Student1 s=(Student1)obj;
		return this.name.equals(s.name)&&this.age==s.age;
	}
	@Override
	public int compareTo(Student1 s) {
		// TODO Auto-generated method stub
		int num=new Integer(this.age).compareTo(new Integer(s.age));
		if(num==0){
			return this.name.compareTo(s.name);
		}
		return num;
	}
	
	
}

//按照學生姓名比較,自定義比較器。

treeMap

import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * 練習: 每一個學生都有對應的歸屬地。 學生Student 地址String 學生屬性:姓名,年齡 注意:姓名和年齡相同的視爲同一個學生。
 * 保證學生的唯一性。
 * 
 * @author Administrator
 * 
 */
public class Test5 {
	public static void main(String[] args) {
		// Map<Student1,String> map=new HashMap<Student1,String>();
		TreeMap<Student1, String> map = new TreeMap<Student1, String>(
				new StuNameComparator());
		map.put(new Student1("blisi1", 21), "beijign");
		map.put(new Student1("lisi2", 22), "shanghai");
		map.put(new Student1("lisi2", 22), "nanjing");
		map.put(new Student1("lisi4", 24), "wuhan");
		// 第一種方式取出keySet
		Set<Student1> keyset = map.keySet();
		Iterator<Student1> it = keyset.iterator();
		while (it.hasNext()) {
			Student1 stu = it.next();
			String addr = map.get(stu);
			System.out.println(stu + ".." + addr);
		}
		// 第二種取出方式:
		/*
		 * Set<Map.Entry<Student1, String>> entrySet=map.entrySet();
		 * Iterator<Map.Entry<Student1, String>> iter=entrySet.iterator();
		 * while(iter.hasNext()){ Map.Entry<Student1, String> me=iter.next();
		 * Student1 stu=me.getKey(); String addr=me.getValue();
		 * System.out.println(stu+"..."+addr); }
		 */
	}
}

class Student1 implements Comparable<Student1> {
	private String name;
	private int age;

	Student1(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;
	}

	public String toString() {
		return name + ":" + age;
	}

	public int hashCode() {
		return name.hashCode() + age * 34;
	}

	public boolean euqals(Object obj) {// 不能加泛型
		if (!(obj instanceof Student)) {
			// return new RuntimeException("類型不匹配");
			throw new ClassCastException("類型不匹配");
		}
		Student1 s = (Student1) obj;
		return this.name.equals(s.name) && this.age == s.age;
	}

	@Override
	public int compareTo(Student1 s) {
		// TODO Auto-generated method stub
		int num = new Integer(this.age).compareTo(new Integer(s.age));
		if (num == 0) {
			return this.name.compareTo(s.name);
		}
		return num;
	}

}

class StuNameComparator implements Comparator<Student1> {

	@Override
	public int compare(Student1 o1, Student1 o2) {
		// TODO Auto-generated method stub
		int num = o1.getName().compareTo(o2.getName());
		if (num == 0) {
			return new Integer(o1.getAge()).compareTo(new Integer(o2.getAge()));
		}
		return num;
	}

}


import java.util.TreeMap;

/**
 * 第一次用a字母作爲鍵去找集合,那麼集合沒有a這個鍵,所以也沒有對應的次數。 返回null, 如果爲null,就將a字母和1存入集合。
 * 如果指定的鍵已經存在,說明有對應的次數,就將對應的次數取出,並自增後再重新存入集合。
 * 
 * @author Administrator 思路: 1,將字符串轉換成字符數組,因爲要對每一個字母進行操作。
 *         2,定義一個map集合,因爲打印結果的字母有順序,所以使用treemap集合。
 *         3,遍歷字符數組,將每一個字母作爲字母作爲鍵去查map集合,如果返回null,就將該字母和1存入map集合中,
 *         如果返回不是null,說明,該字母在map集合中已經存在,並有對應的次數,並獲取該次數,並進行自增。
 *         然後將該字母和子增後的次數存入map集合中,覆蓋原來鍵所對應的值 4,將map集合中的數據變成指定的字符串形式返回。
 */
public class Test6 {
	public static void main(String[] args) {
		String str = "tabdf..daf";
		charCount(str);
	}

	public static String charCount(String str) {

		char[] chs = str.toCharArray();
		int count = 0;
		TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
		for (int x = 0; x < chs.length; x++) {
			if (!(chs[x] >= 'a' && chs[x] <= 'z' || chs[x] >= 'A'
					&& chs[x] <= 'Z')) {
				continue;
			}
			Integer value = tm.get(chs[x]);
			/*
			 * if (value == null) { tm.put(chs[x], 1); } else { value = value +
			 * 1; tm.put(chs[x], value); }
			 */
			if (value != null) {
				count = value;
			}
			count++;
			tm.put(chs[x], count);
			count = 0;
		}
		System.out.println(tm.toString());

		return null;
	}
}



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章