1. 程式人生 > >黑馬程式設計師——集合框架(一) —— Collection

黑馬程式設計師——集合框架(一) —— Collection

------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a>、期待與您交流! ----------

Collection總體概述與常用方法

一、Collection(介面):
     1. List(介面):1.有序的;2.可以儲存重複值;
          ArrayList(類):陣列實現;不同步的,效率高;
          Vector(類):陣列實現;同步的,效率低;
          LinkedList(類):連結串列實現;不同步的,效率高;
     2. Set(介面):1.無序的;2.不能儲存重複值;(全是不同步的)
          HashSet(類):雜湊表實現;驗證重複:hashCode()和equals()
          LinkedHashSet(類):連結串列,雜湊表實現;連結串列:有序;雜湊表:唯一
          TreeSet(類):樹結構;唯一性驗證:比較的方法compareTo()或者compare()方法如果返回0,就不存;
               對元素排序的:
                    1.自然排序:
                        1).儲存的物件必須實現Comparable介面
                        2).重寫compareTo()方法;
                    2.比較器排序:
                        1).自定義比較器,實現Comparator介面
                        2).重寫compare()方法;
                        3).例項化TreeSet物件時,傳遞自定義比較器的物件;(一般我們使用匿名內部類的式) 

二、Collection介面的常用方法:
    1.基本方法:
         boolean add(Object e):將引數e新增到集合
         boolean remove(Object o):將引數o從集合中移除
         void clear():清空集合
         boolean contains(Object o):基於equals()進行判斷;
         boolean isEmpty():判斷集合是否為空
         int size():集合中元素的數量;
    2.批量方法:
         boolean addAll(Collection c):將引數集合,一次性全部新增到當前集合
         boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作
         boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,則返回 true
         boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。
    3.遍歷的方式:
         A.toArray();
         B.Iterator() 

三、針對上述的常用方法,給出部分程式碼演示:

  1.基本方法的用法:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

public class Demo {
	public static void main(String[] args) {
		//1.定義集合物件
		Collection col = new ArrayList();//多型:可儲存重複元素
		Collection col2 = new HashSet();//不能儲存重複元素;
		
		//2.向倉庫中新增元素
		System.out.println(col.add("孫悟空"));
		System.out.println(col.add("豬八戒"));
		System.out.println(col.add("沙師弟"));
		System.out.println(col.add("唐僧"));
		System.out.println(col.add("唐僧"));
		
		System.out.println("---------------------------");
		System.out.println(col2.add("孫悟空"));
		System.out.println(col2.add("豬八戒"));
		System.out.println(col2.add("孫悟空"));
		
		System.out.println("集合元素:" + col);
		//3.移除元素
		System.out.println("刪除元素:唐僧: " + col.remove("唐僧"));
		System.out.println("刪除元素:白骨精:" + col.remove("白骨精"));
		System.out.println("集合元素:" + col);
		
		//4.void clear()
	//	col.clear();
	//	System.out.println("清空集合後:" + col);
		
		//5.boolean contains(Object o)
		System.out.println("是否包含:白骨精:" + col.contains("白骨精"));
		System.out.println("是否包含:孫悟空:" + col.contains("孫悟空"));
		
		//6.boolean isEmpty()
	//	col.clear();
		System.out.println("集合是否為空:" + col.isEmpty());
		
		//7.int size():
		System.out.println("集合中元素的數量:" + col.size());
		
	}
}

2.關於遍歷的方式:

package cn.itcast_collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Iterator_迭代器 {
	public static void main(String[] args) {
		//建立集合物件
		Collection<Student> col = new ArrayList<Student>();
		//將學生物件新增到集合中
		col.add(new Student("北城以北",25,99));
		col.add(new Student("帆@彼岸",26,99));
		/*//使用迭代器(介面)遍歷集合,集合物件呼叫iterator()方法,返回值型別為Iterator介面型別
		Iterator<Student> it = col.iterator();//迭代器的型別隨著集合的明確而明確泛型,這樣下面Student接收值的時候就不需要強轉
		//使用hasNext()加while迴圈判斷是否還有下一個元素,如果有點話,使用next()
		while(it.hasNext()){
			Student stu =  it.next();
			System.out.println("姓名:"+stu.getName()+", 年齡:"+stu.getAge()+", 戰鬥力:"+stu.getScore());
		}*/
		
		//使用for迴圈精簡程式碼
		for(Iterator<Student> it = col.iterator();it.hasNext();){//程式碼初始化;判斷是否有下一個;(迴圈操作可以省略)
			Student stu =  it.next();
			System.out.println("姓名:"+stu.getName()+", 年齡:"+stu.getAge()+", 戰鬥力:"+stu.getScore());
		}
	}
	
}

關於ArrarList的應用

    集合中,ArrayList是最常用的一種集合,因此這是我們必須要掌握的知識!但是,ArrayList沒有特有方法,都是使用的父介面中定義的。即:Collection和List中的方法。

    Collection在上面已經講過,這裡講一下List的特有方法。

    List介面的常用方法:
        1).新增的方法:
           void add(int index,E element)
           E remove(int index)
           E get(int index)
           E set(int index,E element)
           ListIterator listIterator()
        2).遍歷的方式:
           A.結合Collection的size()和List的get()方法,使用for()迴圈;
           B.ListIterator:可以向前遍歷,也可以向後遍歷;
    Iterator 和 ListIterator的區別:
        1.ListIterator是Iterator的子介面;
        2.Iterator只能向下遍歷;
        3.ListIterator可以雙向遍歷;

    對於這些基本方法,這裡就不做演示了,大家可以參考Collection中關於基本方法的演示自己試著做一下。下面給出一個例子。這個例子是關於怎樣去除ArrayList中重複的元素:

    這裡給出了兩種方法,大家參考一下:


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

/*
 * 
 * 方式一:定義一個新集合;
 * 方式二:遍歷當前集合,在當前集合的基礎上進行修改;
 */
public class Demo {
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add(new Student("李四",22));
		list.add(new Student("李四",22));
		list.add(new Student("李四",22));
		list.add(new Student("張三",20));
		list.add(new Student("李四",22));
		list.add(new Student("李四",22));
		list.add(new Student("王五",24));
		list.add(new Student("王五",24));
		list.add(new Student("王五",24));
		list.add(new Student("王五",24));
		list.add(new Student("王五",24));
		/*
		//方式一:
		List newList = new ArrayList();
		
		//遍歷
		loop:
		for(int i = 0;i < list.size() ;i++){
			Student stu = (Student)list.get(i);
			for(int j = 0;j < newList.size() ; j++){
				Student stu2 = (Student)newList.get(j);
				if(stu.equals(stu2)){
					continue loop;
				}
			}
			//將stu新增到newList中
			newList.add(stu);
		}
		
		//遍歷newList
		for(int i = 0 ;i < newList.size() ; i++){
			Student stu = (Student)newList.get(i);
			System.out.println(stu.name + "," + stu.age);
		}*/
		
		//方式二:
		for(int i = 0; i < list.size() - 1 ; i++){
			Student stu1 = (Student)list.get(i);
			for(int j = i + 1 ; j < list.size() ; j++){
				Student stu2 = (Student)list.get(j);
				if(stu1.equals(stu2)){
					list.remove(j);
					j--;
				}
			}
		}
		//遍歷原集合
		for(int i = 0; i < list.size() ; i++){
			Student stu = (Student)list.get(i);
			System.out.println(stu.name + "," + stu.age);
		}
		
	}
}

泛型


 1.在定義集合時,可以指定這個集合內只能裝什麼型別元素,這種方式就是“泛型”
     ArrayList<String> strList = new ArrayList<String>();
     或:
     ArrayList<String> strList = new ArrayList<>();
     或:
    ArrayList<String> strList = new ArrayList();
 2.泛型類:class MyArrayList<T>{}
         1.T:可以是任何字母;大小寫都可以;
         2.也可以定義多個泛型,中間用逗號隔開;<T,V>
 3.泛型方法:
     class MyArrayList{
     //接收的是什麼型別,返回的就是具有這個型別
      public <T> T show(T t){
      return t;
     }
   }
 4.泛型介面:
    interface IA<T>{
     T show(T t);
   }
   子類實現時:
       1.可以繼續定義泛型:
        class A <T> implements IA<T>{
          public T show(T t){
         }
        }
       2.可以固定為某個具體型別
        class A  implements IA<String>{
          public String show(String s){
          }
       }
       3.可以將泛型丟棄
         class A implements IA{
         public Object show(Object o){
         }
       }
 5.泛型的萬用字元:
  1:<?>:
  2:<? extends E>:
  3:<? super E>:

這裡關於泛型萬用字元不是很好理解,給出一個Demo幫助大家快速掌握:

package cn.itcast.demo11_泛型萬用字元;

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

/*
 * 泛型萬用字元:
 * 1.<?> : 
 * 		1).變數可以指向什麼型別的物件:具有任何泛型的集合物件;
 * 		2).可以儲存什麼東西:由於?不確定具體型別,所以不能add()任何型別
 * 		3).取出時用什麼接收:只能用Object接收;
 * 	 作用:不能存入,只能獲取,所以一般用作方法的返回值宣告;
 * 2.<? extends E> :
 * 		1).變數可以指向什麼型別的物件:具有E泛型或者E子類泛型的集合;
 * 		2).可以儲存什麼東西:由於不確定是哪個E的子類,所以不能存任何東西;
 * 		3).取出時用什麼接收:只能用E及E的父類型別接收;
 * 3.<? super E> : 
 * 		1).變數可以指向什麼型別的物件:具有E泛型或者E父類泛型的集合;
 * 		2).可以儲存什麼東西:只能儲存E或者E的子類物件;
 * 		3).取出時用什麼接收:由於儲存的可能是任何的E的子類物件,所以只能用Object接收;
 */
class Animal{}
class Cat extends Animal{};
class Dog extends Animal{};
class JMDog extends Dog{};
public class Demo {
	public static void main(String[] args) {
		//1.<?>
		List<?> list1 = new ArrayList<>();
		List<?> list2 = new ArrayList<String>();
		List<?> list3 = new ArrayList<Animal>();
//		
//		list2.add("aa");
//		list2.add(10);
//		list2.add(new Animal());
		
		Object obj = list2.get(0);
		
		//2.<? extends E>
	//	List<? extends Dog> list4 = new ArrayList<Animal>();//編譯錯誤
		List<? extends Dog> list5 = new ArrayList<Dog>();
		List<? extends Dog> list6 = new ArrayList<JMDog>();
		/*
		list5.add("你好");
		list5.add(10);
		list5.add(new Animal());
		list5.add(new Dog());
		list5.add(new JMDog());
		*/
		Dog d1 = list5.get(0);
		Animal a1 = list5.get(0);
		
		//3.<? super E>
		List<? super Dog> list7 = new ArrayList<Animal>();
		List<? super Dog> list8 = new ArrayList<Dog>();
	//	List<? super Dog> list9 = new ArrayList<JMDog>();
		
	//	list7.add(new Animal());
		list7.add(new Dog());
	//	list7.add(new Cat());
		list7.add(new JMDog());
		
		Object d = list7.get(0);
		
		
	}
}

Set集合

Set集合:這裡不是特別好理解,對於初學者,能掌握則好,掌握不了能看懂就可以。
    1.Set集合的特點:
       1).無序(取出時,跟存入時的順序不一致)
       2).不儲存重複元素。
    2.子類:
       1).HashSet:
          A.內部使用"雜湊表"結構;
          B.使用hashCode()和equals()保證元素的唯一;
       2).TreeSet:
          A.內部使用"樹"結構;
          B.比較方式:
             1.自然排序:
                自定義類實現Comparable介面。重寫compareTo()
             2.比較器排序:
                自定義"比較器"實現Comparator介面,重寫compare()方法;
                例項化TreeSet時,將"比較器"物件傳入;
          C.無論哪種比較方式,只要返回0,就認為是相等的物件,不存。
  
       3).LinkedHashSet:有序的;
          A.內部使用連結串列、雜湊表實現;
          B.由連結串列保證有序;由雜湊表保證唯一

這裡給出HashSet儲存自定義物件時候需要重寫hashCode()和equals()做一個示例:兩個類Student類和Demo類

import java.util.HashSet;
import java.util.Set;
/*
 * 使用HashSet儲存自定義物件
 * 
 * 1.需要判斷出兩個物件中的屬性值是否完全一樣,需要重寫hashCode()和equals();
 * 2.怎麼重寫?
 * 		滑鼠-->右鍵-->source-->Generate hashCode() and equals()
 */
public class Demo {
	public static void main(String[] args) {
		//建立集合物件,並新增元素
		Set<Student> stuSet = new HashSet<>();
		stuSet.add(new Student("張三",20));
		stuSet.add(new Student("李四",22));
		stuSet.add(new Student("王五",24));
		stuSet.add(new Student("王五",24));
		
		//遍歷集合並輸出
		for(Student stu : stuSet){
			System.out.println(stu.name + "---" + stu.age);
		}
		
		
		
	}
}

 這裡Student類中重寫了equals()和HashCode()方法:

public class Student {
	String name;
	int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@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;
		Student other = (Student) 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;
	}
	
}

public class Student {
	String name;
	int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@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;
		Student other = (Student) 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;
	}
	
}


public class Student {
 String name;
 int age;
 public Student(String name, int age) {
  super();
  this.name = name;
  this.age = age;
 }
 @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;
  Student other = (Student) 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;
 }
 
}


一.Set集合:
 1.Set集合的特點:
  1).無序(取出時,跟存入時的順序不一致)
  2).不儲存重複元素。
 2.子類:
  1).HashSet:
   A.內部使用"雜湊表"結構;
   B.使用hashCode()和equals()保證元素的唯一;
  2).TreeSet:
   A.內部使用"樹"結構;
   B.比較方式:
    1.自然排序:
     自定義類實現Comparable介面。重寫compareTo()
    2.比較器排序:
     自定義"比較器"實現Comparator介面,重寫compare()方法;
     例項化TreeSet時,將"比較器"物件傳入;
   C.無論哪種比較方式,只要返回0,就認為是相等的物件,不存。
  
  3).LinkedHashSet:有序的;
   A.內部使用連結串列、雜湊表實現;
   B.由連結串列保證有序;由雜湊表保證唯一


二:泛型:
 1.在定義集合時,可以指定這個集合內只能裝什麼型別元素,這種方式就是“泛型”
  ArrayList<String> strList = new ArrayList<String>();
  或:
  ArrayList<String> strList = new ArrayList<>();
  或:
  ArrayList<String> strList = new ArrayList();
 2.泛型類:class MyArrayList<T>{}
                 1.T:可以是任何字母;大小寫都可以;
                 2.也可以定義多個泛型,中間用逗號隔開;<T,V>
 3.泛型方法:
  class MyArrayList{
   //接收的是什麼型別,返回的就是具有這個型別
   public <T> T show(T t){
    return t;
   }
  }
 4.泛型介面:
  interface IA<T>{
   T show(T t);
  }
   子類實現時:
  1.可以繼續定義泛型:
   class A <T> implements IA<T>{
    public T show(T t){
    }
   }
  2.可以固定為某個具體型別
   class A  implements IA<String>{
    public String show(String s){
    }
   }
  3.可以將泛型丟棄
   class A implements IA{
    public Object show(Object o){
    }
   }
 5.泛型的萬用字元:見Demo
  1:<?>:
  2:<? extends E>:
  3:<? super E>:二:泛型:
 1.在定義集合時,可以指定這個集合內只能裝什麼型別元素,這種方式就是“泛型”
  ArrayList<String> strList = new ArrayList<String>();
  或:
  ArrayList<String> strList = new ArrayList<>();
  或:
  ArrayList<String> strList = new ArrayList();
 2.泛型類:class MyArrayList<T>{}
                 1.T:可以是任何字母;大小寫都可以;
                 2.也可以定義多個泛型,中間用逗號隔開;<T,V>
 3.泛型方法:
  class MyArrayList{
   //接收的是什麼型別,返回的就是具有這個型別
   public <T> T show(T t){
    return t;
   }
  }
 4.泛型介面:
  interface IA<T>{
   T show(T t);
  }
   子類實現時:
  1.可以繼續定義泛型:
   class A <T> implements IA<T>{
    public T show(T t){
    }
   }
  2.可以固定為某個具體型別
   class A  implements IA<String>{
    public String show(String s){
    }
   }
  3.可以將泛型丟棄
   class A implements IA{
    public Object show(Object o){
    }
   }
 5.泛型的萬用字元:見Demo
  1:<?>:
  2:<? extends E>:
  3:<? super E>:二:泛型:
 1.在定義集合時,可以指定這個集合內只能裝什麼型別元素,這種方式就是“泛型”
  ArrayList<String> strList = new ArrayList<String>();
  或:
  ArrayList<String> strList = new ArrayList<>();
  或:
  ArrayList<String> strList = new ArrayList();
 2.泛型類:class MyArrayList<T>{}
                 1.T:可以是任何字母;大小寫都可以;
                 2.也可以定義多個泛型,中間用逗號隔開;<T,V>
 3.泛型方法:
  class MyArrayList{
   //接收的是什麼型別,返回的就是具有這個型別
   public <T> T show(T t){
    return t;
   }
  }
 4.泛型介面:
  interface IA<T>{
   T show(T t);
  }
   子類實現時:
  1.可以繼續定義泛型:
   class A <T> implements IA<T>{
    public T show(T t){
    }
   }
  2.可以固定為某個具體型別
   class A  implements IA<String>{
    public String show(String s){
    }
   }
  3.可以將泛型丟棄
   class A implements IA{
    public Object show(Object o){
    }
   }
 5.泛型的萬用字元:見Demo
  1:<?>:
  2:<? extends E>:
  3:<? super E>:


package cn.itcast_collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Iterator_迭代器 {
	public static void main(String[] args) {
		//建立集合物件
		Collection<Student> col = new ArrayList<Student>();
		//將學生物件新增到集合中
		col.add(new Student("北城以北",25,99));
		col.add(new Student("帆@彼岸",26,99));
		/*//使用迭代器(介面)遍歷集合,集合物件呼叫iterator()方法,返回值型別為Iterator介面型別
		Iterator<Student> it = col.iterator();//迭代器的型別隨著集合的明確而明確泛型,這樣下面Student接收值的時候就不需要強轉
		//使用hasNext()加while迴圈判斷是否還有下一個元素,如果有點話,使用next()
		while(it.hasNext()){
			Student stu =  it.next();
			System.out.println("姓名:"+stu.getName()+", 年齡:"+stu.getAge()+", 戰鬥力:"+stu.getScore());
		}*/
		
		//使用for迴圈精簡程式碼
		for(Iterator<Student> it = col.iterator();it.hasNext();){//程式碼初始化;判斷是否有下一個;(迴圈操作可以省略)
			Student stu =  it.next();
			System.out.println("姓名:"+stu.getName()+", 年齡:"+stu.getAge()+", 戰鬥力:"+stu.getScore());
		}
	}
	
}