黑馬程序員-java基礎-集合

-------------------------ASP.Net+Unity開發、.Net培訓、期待與您交流!--------------------------

集合

1、集合的特點
第一,集合是用來存儲對象的,而且存儲的是對象的地址而不是對象本身。
第二,集合中可以存儲任何類型的對象,並且集合的長度可變。
2、集合和數組的區別
集合可以存儲任何類型的元素,而數組只能存儲相同類型的元素;
集合的長度可變,而數組的長度是固定的。
3、集合的分類
List :元素是有序的,元素可以重複
LinkedList:底層的數據結構使用的是鏈表數據結構
ArrayList:底層的數據結構使用的是數組數據結構
Set :元素是無序的,元素不可以重複
HashSet :底層的數據結構使用的是哈希表
TreeSet :底層的數據結構使用的是二叉樹
-----------------------------------------------------------------------------------
集合的共性方法
1
、添加元素:boolean add(Object obj)
2、刪除元素:boolean remove(元素)
3、清空集合:void clear()
4、判斷元素:boolean contain(元素)
判斷集合是否爲空:boolean isEmpty()
5、獲取元素個數:int size()
6、取出元素利用迭代器:Interator it=集合.iterator();

例子:

/*
Collection 集合中的共性方法
*/
import java.util.*;
class  CollectionDemo
{
	public static void main(String[] args) 
	{
		/*
		1.//未使用泛型時的情況 由於並未固定集合中元素的類型   所以什麼類型都行
		ArrayList al=new ArrayList();//定義一個容器
		al.add("java01");
		al.add("java02");
		al.add(4);
		Iterator it=al.iterator();
		while (it.hasNext())
		{
			sop(it.next());	
		}
		*/
		//2.使用泛型的情況 則集合中元素的類型就是固定的
		ArrayList<String> al=new ArrayList<String>();
		al.add("java01");//給集合添加元素  其實爲Object obj ="java01";即多態  向上轉型
		al.add("java02");
		al.remove("java03");//刪除集合中的元素  
		//al.add(4);
		Iterator<String> it=al.iterator();//遍歷集合中的元素
		while (it.hasNext())
		{
			String s=(String)it.next();//由於確定了是什麼類型 所以可以向下轉型 所以可以利用字符串的特有屬性 方法。
			sop(s);
			sop("長度爲:"+s.length());	
		}
		sop(al.size());
		sop(al.contains("java01"));
	}
	public static void sop(Object b)
	{
		System.out.println(b);
	}
}
------------------------------------------------------------------------------------
List集合
1、
包括:ArrayList LinkedList
2、List集合的共性方法:
在指定位置添加元素:void add(int index,元素)
刪除指定位置的元素:元素類型 remove(int index)
修改指定位置的元素:元素類型 set(int index,newElement)
通過角標獲取指定位置元素:元素類型 get(int index)
3.List集合的特有迭代器:ListIterator
ListIterator 是Iterator的子接口,在迭代的過程中,不可以通過集合對象的方法來操作
集合中的元素,會發生ConcurrentModificationException異常。所以在迭代時,只能用迭代器的方法
來操作元素,可是Iterator的方法是有限的,只能對元素進行判斷,取出,刪除的動作。如果想要其他的
操作,如添加、修改等,就需要使用其子接口ListIterator。
創建ListIterator對象:ListIterator li=al.listIterator();
例子:

/*
List集合中的共性方法
*/
import java.util.*;
class ListDemo 
{
	public static void main(String[] args) 
	{
		ArrayList al=new ArrayList();
		al.add("java01");
		al.add("java02");
		al.add(1,"java hello");//List集合的特有方法 即通過角標對集合進行操作
		//通過通用方法對集合進行遍歷
		Iterator it=al.iterator();
		while (it.hasNext())
		{
			sop(it.next());	
		}
		//sop(al);
		sop("-------------------------");
		//通過List集合的特有迭代器來對集合進行訪問 此迭代器在迭代的過程中可以對集合進行別的操作
		ListIterator li=al.listIterator();
		while (li.hasNext())
		{
			Object obj=li.next();
			if (obj.equals("java02"))
			{
				//li.add("java003");//在迭代的過程中進行添加元素
				li.set("java002");//在迭代的過程中進行修改元素(這兩個方法不可以同時進行操作 因爲不知道該不該操作此元素)
			}
			sop(obj);//依然打印不出新添加的元素	
		}
		//sop(al);
		for (int x=0;x<al.size() ;x++ )
		{
			sop(al.get(x));//通過List的特有方法即通過角標對元素進行方法 遍歷。
		}
	}
	public static void sop(Object b)
	{
		System.out.println(b);
	}
}
------------------------------------------------------------------------------------
LinkedList
1
、它的特有方法
添加元素:void addFirst(E e)//在集合的第一個位置添加元素
void addLast(E e) //在集合的最後一個位置添加元素
獲取元素: E getFirst() //獲取此集合的第一個元素
E getLast() //獲取此集合的最後一個元素
刪除元素: E removeFirst()//移除此集合的第一個元素,並返回此元素
E removeLast() //移除此集合的最後一個元素,並返回此元素
2、對於此集合而得到的思想
由於此集合具有在第一個位置和最後一個位置添加元素的特性以及移除第一個位置和移除
第二個位置元素的額特性。則可以通過此集合來模擬一個堆棧或者隊列的數據結構
具體程序如下:

具體程序如下:
/**
需求:使用LinkedList模擬一個堆棧或者隊列的數據結構。
思路:1.要想模擬堆棧或者隊列的數據結構 首先應該知道他們的特點
		 堆棧:先進後出
		 隊列:先進先出
	  2.根據他們的特點  然後再創建相應的方法--存入方法 和取出方法
	  3.使用LinkedList中的方法來實現堆棧和隊列
步驟:
1,定義一個類來實現堆棧或者隊列
2,定義此類中的成員變量和成員函數
3,成員函數即實現此堆棧或者隊列的特點 即利用LinkedList中的特有方法來實現
*/
import java.util.*;
class DuiZhan
{
	private LinkedList ll;
	DuiZhan()
	{
		ll=new LinkedList();

	}
	//實現存放的功能
	public void set(Object obj)
	{
		ll.addFirst(obj);
	}
	//實現獲取的功能
	public Object get()
	{
		return ll.removeFirst();
	}
	public int size()
	{
		return ll.size();
	}
  public boolean isNull()
	{
		return ll.isEmpty();
    }
}
class LinkedListDemo 
{
	public static void main(String[] args) 
	{
		DuiZhan dz=new DuiZhan();
		dz.set("java05");
		dz.set("java02");
		dz.set(3);
		int y=dz.size();
		for (int x=0; x<y;x++ )//此處不能直接寫x<dz.size() 因爲循環一次則調用一次dz.size()
		                       //所以長度會慢慢減小
		{
			sop(dz.get());
		}
	}
	public static void sop(Object b)
	{
		System.out.println(b);
	}
}
------------------------------------------------------------------------------------
Set集合中的方法和Collection的共性方法是一樣的。下面具體介紹Set的兩個子類的作用和方法
HashSet
1
、存儲的元素是無序的,元素是無重複,並且存入的是自定義對象。
2、HashSet是如何保證元素的唯一性的呢?
是通過元素的兩個方法:hashCode和equals來完成的。如果元素的hashCode值相同,纔會判斷
equals是否是true。如果元素的hashCode值不同,不會調用equals方法。所以對於自定義對象,要
存入HashSet集合中,爲了保證元素的唯一性,必須複寫HashCode方法和equals方法。
3、對於HashSet集合中判斷元素是否存在以及刪除元素,依賴的也是HashCode方法和equals方法
4、注意:hashCode方法本身比較的是對象的地址值。所以若不復寫,則是去除不了重複元素的。

例子:需求:向HashSet集合中存入自定義Person對象
	import java.util.*;
	class HashSetTest 
	{
		public static void sop(Object b)
		{
			System.out.println(b);
		}
		public static void main(String[] args) 
		{
			HashSet hs=new HashSet();
			hs.add(new Person("a1",71));
			hs.add(new Person("a2",73));
			hs.add(new Person("a3",74));
			hs.add(new Person("a1",71));
			//遍歷此集合
			Iterator it=hs.iterator();
			while (it.hasNext())
			{
				//向下轉型,爲了用Person類的特有方法
				Person p=(Person)it.next();
				sop(p.getName()+"::"+p.getAge());	
			}
		}
	}
	class Person
	{
		private String name;
		private int age;
		Person(String name,int age)
		{
			this.name=name;
			this.age=age;
		}
		//複寫hashCode方法
		public int hashCode()
		{
			return name.hashCode()+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;
		}
		public String getName()
		{
			return name;
		}
		public int getAge()
		{
			return age;
		}
	}
----------------------------------------------------------------------------------
TreeSet
1
、TreeSet集合的底層數據結構爲二叉樹
2、此集合可以對Set集合中的元素進行排序(按字母的自然順序,且大寫的在小寫的字母前面)
3、TreeSet集合對元素進行排序的原理
此元素需要實現Comparable接口並複寫comparaTo方法,才能對元素進行排序
4、TreeSet集合存儲自定義對象,對對象實現排序功能的方法有兩種;
第一,元素自身具備比較性,即實現Comparable接口並複寫comparaTo方法
第二,集合本身具備比較性,即在集合的構造函數裏傳入Comparator接口類型的對象。
即,定義一個類實現Comparator接口,並覆蓋compara方法。並將此類對象作爲參數傳遞給
TreeSet集合的構造函數中。
注意,當這兩中排序方式同時都存在時,則集合本身具備比較性優先。
注意,在比較的時候,當主要條件相同時,則判斷次要條件。

/*
需求:向集合TreeSet中存入自定義對象Student,並按年齡進行排序,將年齡和名字相同者視爲同一個人。
*/
//元素自身具備比較性
class Student implements Comparable
{
	private int age;
	private String name;
	Student(int age,String name)
	{
		this.age=age;
		this.name=name;
	}
	//複寫Comparable接口的方法Comparable
	public int comparaTo(Object obj)
	{
		if (!(obj instanceof Student))
		{
			throw new RuntimeException("不是學生對象");
		}
		Student s=(Student)obj;
		if (this.age>s.age)
			return 1;
		if (this.age=age)//當主要條件相等時,比較次要條件
			return this.name.comparaTo(p.name);
		return -1;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}
//第二種方式排序,即用比較器,使集合自身具備比較性
class MyCompara implements Comparator
{
	public int compara(Object 01,Object 02)
	{
		Student s1=(Student)01;
		Student s2=(Student)02;
		//以姓名排序
		int num=s1.getName().comparaTo(s2.getName());
		if (num==0)
		{
			//當主要條件相同時,看次要條件。
			return new Integer(s1.getAge()).comparaTo(new Integer(s2.getAge()));
		}
		return num;
	}
}
class TreeSetTest 
{
	public static void main(String[] args) 
	{
		TreeSet ts=new TreeSet(new MyCompara());//讓集合自身具備比較功能
		ts.add(new Student("lisi02",22));
		ts.add(new Student("lisi02",21));
		ts.add(new Student("lisi007",20));
		ts.add(new Student("lisi09",19));
		ts.add(new Student("lisi06",18));
		ts.add(new Student("lisi06",18));
		Iterator it = ts.iterator();
		//對集合進行遍歷
		while(it.hasNext())
		{
			Student stu = (Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());
		}
	}
}
--------------------------------------------------------------------------------
Map 集合
1
、Map集合並不是Collection的一種,它是獨立的接口
2、Map集合的特點
該集合存儲鍵值對,一對一對往裏存,而且保證鍵的唯一性。
3、Map的子類:
Hashtable:底層是哈希表數據結構,不可以存入null鍵和null值
用作鍵的對象必須實現hashCode方法和equals方法;該集合是
線程同步的。
HashMap:底層是哈希表數據結構,允許使用null值和null鍵,該集合是不同步的。效率較高
TreeMap:底層是二叉樹數據結構,線程不同步。可以用於給Map集合中的鍵進行排序。
Map和Set很像,其實Set底層就是使用了Map集合。
4、Map集合的共性方法
添加元素: V put(K key, V value )
刪除元素: V remove(Object key)
清空集合:void clear()
判斷: boolean containsKey(Object key)
如果此映射包含指定鍵的映射關係,則返回 true。
boolean containsValue(Object value)
如果此映射將一個或多個鍵映射到指定值,則返回 true
boolean isEmpty()//判斷集合是否是空的。
獲取: V get(Object key) //獲取鍵所對應的值
int size() //獲取集合的大小
5、對於Map集合中元素的取出方式
第一,利用keySet:將map中的所有鍵存入set集合,因爲set具備迭代器,所以可以通過迭代器
方式取出所有的鍵,再根據get方法,獲取每一個鍵對應的值。
第二,entrySet:將map集合的映射關係直接存入到了set集合中,而這個關係數據類型就是Map.Entry
Entry其實就是Map中的一個static內部接口。
代碼:

import java.util.*;
class MapDemo2 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
		map.put("01","zhangsan1");
		map.put("04","zhangsan4");
		//第二種排序方式
		//將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 value = me.getValue();

			System.out.println(key+":"+value);

		}
		/*第一種排序方式
		//先獲取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);
		}
		*/
	}
}
--------------------------------------------------------------------------
HashMap保證元素唯一性的原理和HashSet是一樣的,所以不再贅述
TreeSet對元素的排序原理和TreeSet是一樣的,同樣不再贅述。
練習:對於HashMap集合的練習

/*
每一個學生都有對應的歸屬地。
學生Student,地址String。
學生屬性:姓名,年齡。
注意:姓名和年齡相同的視爲同一個學生。
保證學生的唯一性。
獲取map集合中的元素。
*/

import java.util.*;
class Student 
{
	private String name;
	private int age;
	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	//複寫hashCode方法
	public int hashCode()
	{
		return name.hashCode()+age*34;
	}
	//複寫equals方法
	public boolean equals(Object obj)
	{
		if(!(obj instanceof Student))
			throw new ClassCastException("類型不匹配");

		Student s = (Student)obj;

		return this.name.equals(s.name) && this.age==s.age;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
	public String toString()
	{
		return name+":"+age;
	}
}
class  MapTest
{
	public static void main(String[] args) 
	{
		HashMap<Student,String> hm = new HashMap<Student,String>();

		hm.put(new Student("lisi1",21),"beijing");
		hm.put(new Student("lisi1",21),"tianjin");
		hm.put(new Student("lisi2",22),"shanghai");
		hm.put(new Student("lisi3",23),"nanjing");
		hm.put(new Student("lisi4",24),"wuhan");
		//利用 keySet取出元素
		Set<Student> keySet = hm.keySet();
		Iterator<Student> it = keySet.iterator();
		while(it.hasNext())
		{
			Student stu = it.next();
			String addr = hm.get(stu);
			System.out.println(stu+".."+addr);
		}
	}
}
練習:對TreeSet集合的練習
/*
練習:
"sdfgzxcvasdfxcvdf"獲取該字符串中的字母出現的次數。
希望打印結果:a(1)c(2).....

通過結果發現,每一個字母都有對應的次數。
說明字母和次數之間都有映射關係。所以選擇map

思路:
1,將字符串轉換成字符數組。因爲要對每一個字母進行操作。
2,定義一個map集合,因爲打印結果的字母有順序,所以使用treemap集合。
3,遍歷字符數組。
	將每一個字母作爲鍵去查map集合。
	如果返回null,將該字母和1存入到map集合中。
	如果返回不是null,說明該字母在map集合已經存在並有對應次數。
	那麼就獲取該次數並進行自增。,然後將該字母和自增後的次數存入到map集合中。覆蓋調用原理鍵所對應的值。
4,將map集合中的數據變成指定的字符串形式返回。
*/
import java.util.*;
class  MapTest3
{
	public static void main(String[] args) 
	{
		String s= charCount("ak+abAf1c,dCkaAbc-defa");
		System.out.println(s);
	}
	public static String charCount(String str)
	{
		char[] chs = str.toCharArray();
		//將字母和字母出現的次數作爲映射存入集合中
		TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
		int count = 0;
		//遍歷數組
		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)
				count = value;
			count++;
			tm.put(chs[x],count);//直接往集合中存儲字符和數字,爲什麼可以,因爲自動裝箱。
			count = 0;
		StringBuilder sb = new StringBuilder();
		//取出集合中的元素,並存入StringBuilder中
		Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
		Iterator<Map.Entry<Character,Integer>>  it = entrySet.iterator();
		while(it.hasNext())
		{
			Map.Entry<Character,Integer> me = it.next();
			Character ch = me.getKey();
			Integer value = me.getValue();
			sb.append(ch+"("+value+")");
		}
		return sb.toString();
	}
}


-------------------------ASP.Net+Unity開發、.Net培訓、期待與您交流!--------------------------


詳情請查看:http://edu.csdn.net





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