黑馬程式設計師java之集合框架Collection
------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a>、期待與您交流! ----------
Collection
|--List:元素是有序的,元素可以重複。因為該集合體繫有索引。
List集合判斷元素是否相同,依據是元素的equals方法。
|--ArrayList:底層的資料結構使用的是陣列結構。特點:查詢速度很快。但是增刪稍慢。執行緒不同步。
|--LinkedList:
|--Vector:底層是陣列資料結構。執行緒同步。被ArrayList替代了。因為效率低。
|--Set:元素是無序(存入和取出的順序不一定一致),元素不可以重複。
|--HashSet:底層資料結構是雜湊表。是執行緒不安全的。不同步。
HashSet保證元素唯一性是通過元素的兩個方法,hashCode和equals來完成。如果元素的HashCode值相同,才會判斷equals是否為true。如果元素的hashcode值不同,不會呼叫equals。
注意,對於判斷元素是否存在,以及刪除等操作,依賴的方法是元素的hashcode
|--TreeSet可以對Set集合中的元素進行排序。底層資料結構是二叉樹。
Collection定義了集合框架的共性功能。
1,新增add(e);新增e進入集合
2,刪除remove(e);removeAll();刪除全部元素
3,判斷。contains(e);判斷e是否存在。
isEmpty();判斷集合是否為空。
4,獲取
iterator();通過迭代獲取集合全部元素
size();獲取集合元素個數
5,獲取交集。retainAll();
6,集合變陣列。toArray();
集合的取出元素的方式。是用迭代器 Iterator
Iterator it = al.iterator();
while(it.hasNext()){//判斷集合是否有元素
sop(it.next());//列印元素
}
for(Iterator it = al.iterator(); it.hasNext() ; ){
sop(it.next());
}開發建議用這種,節省記憶體。
List特有方法。凡是可以操作角標的方法都是該體系特有的方法。
增add(index,element);在指定位置新增元素。
addAll(index,Collection);
刪remove(index);
改set(index,element);
查get(index):獲取指定角標元素subList(from,to);
int indexOf(obj):獲取指定元素的位置。
ListIterator listIterator();list特有方法列表迭代器
Iterator迭代器只能對元素進行判斷,取出,刪除的操作,
如果想要其他的操作如新增,修改等,就需要使用其子介面,ListIterator。
package pract;
import java.util.ArrayList;
import java.util.ListIterator;
public class ArrayListDemo {
/**
* 12、一個ArrayList物件aList中存有若干個字串元素,現欲遍歷該ArrayList物件,
刪除其中所有值為"abc"的字串元素,請用程式碼實現。
思路:
1,建立一個ArrayList物件 並存儲若干字元
2,遍歷物件 刪除元素
* */
public static void main(String[] args) {
// 建立ArrayList物件
ArrayList<String> al = new ArrayList<String>();
al.add("addf");//新增若干元素。
al.add("abc");
al.add("adabcddf");
al.add("abcd");
al.add("abc");
//用迭代器遍歷集合ArrayList,ListIterator是List特有迭代器
ListIterator<String> li = al.listIterator();
while(li.hasNext())//判斷集合是否有元素
{
String s = li.next();//獲取集合元素
//當集合元素和adc相同時
if(s.equals("abc"))
li.remove();//在集合中刪除該元素
}
System.out.println(al);//列印結果:[addf, adabcddf, abcd]
}
}
LinkedList:特有方法:
addFirst();addLast();新增元素
getFirst();getLast();
獲取元素,但不刪除元素。如果集合中沒有元素,會出現NoSuchElementException
removeFirst();removeLast();
獲取元素,但是元素被刪除。如果集合中沒有元素,會出現NoSuchElementException
在JDK1.6出現了替代方法。
offerFirst();offerLast();新增元素
peekFirst();peekLast();
獲取元素,但不刪除元素。如果集合中沒有元素,會返回null。
pollFirst();pollLast();
獲取元素,但是元素被刪除。如果集合中沒有元素,會返回null。
package pract;
import java.util.LinkedList;
public class LinkedListTest {
/**
* 使用LinkedList模擬一個堆疊或者佇列資料結構。
堆疊:先進後出 如同一個杯子。
佇列:先進先出 如同一個水管。
思路:用LinkedList模擬,先進先出
1,用LinkedList的addFirst新增,因為每一次加入都是第一個元素,所以第一次加入的元素
在記憶體中就變成最後一個,所以取出的時候用removeLast就會取出最後元素並刪除,下次還能去最
後一個。先進後出同理也是一樣,只不過把取出方式變成先刪除第一個而已。
*/
public static void main(String[] args) {
//
DuiLie dl = new DuiLie();//建立DuiLie物件
dl.myAdd("java01");
dl.myAdd("java02");//新增元素,底層呼叫LinkedList.addFirst()方法
dl.myAdd("java03");
dl.myAdd("java04");
while(!dl.isNull())//判斷是否為空,底層呼叫LinkedList.isEmpty()方法
{
System.out.println(dl.myGet());
//獲取元素,底層呼叫LinkedList.removeLast()刪除
}
DuZhan d2 = new DuZhan();
d2.myAdd("zhangsan");
d2.myAdd("lisi");
d2.myAdd("wangwu");
d2.myAdd("xiaoliu");
while(!d2.isNull())
{
System.out.println(d2.myGet());
}
}
}
class DuiLie
{
private LinkedList<Object> link;
DuiLie()
{//物件一初始化就創立LiskedList物件
link = new LinkedList<Object>();
}
public void myAdd(Object obj)
{
link.addFirst(obj);//用LinkedList的addFirst加入
}
public Object myGet()
{
return link.removeLast();//用//用LinkedList的removeLast刪除
}
public boolean isNull()//判斷集合是否為空
{
return link.isEmpty();
}
}
class DuZhan{
private LinkedList<Object> link ;
DuZhan(){
link = new LinkedList<Object>();
}
public void myAdd(Object obj)
{
link.addFirst(obj);
}
public Object myGet()
{
return link.removeFirst();
}
public boolean isNull()
{
return link.isEmpty();
}
}
程式執行結果:
java01
java02
java03
java04
xiaoliu
wangwu
lisi
zhangsan
Vector:列舉就是Vector特有的取出方式。發現列舉和迭代器很像。其實列舉和迭代是一樣的。因為列舉的名稱以及方法的名稱都過長。所以被迭代器取代了。
Enumeration en = v.elements();
while(en.hasMoreElements()){
System.out.println(en.nextElement());
}
Set集合的功能和Collection是一致的。
HashSet元素需要複寫hashCode();如果hash值相同,還需要比較equals。HashCode()返回值是int而equals是boolean型
package pract;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetDemo {
/**
* 往hashSet集合中存入自定物件
姓名和年齡相同為同一個人,重複元素。
*/
public static void main(String[] args) {
HashSet<People> hs = new HashSet<People>();
hs.add(new People("a1",11));
hs.add(new People("a2",12));
hs.add(new People("a3",13));
hs.add(new People("a3",13));
//迭代器遍歷集合元素
Iterator<People> it = hs.iterator();
while(it.hasNext())//判斷集合是否有元素
{
People p = it.next();//獲取物件元素
System.out.println(p.getName()+"::"+p.getAge());
//輸出物件姓名和年齡
}
}
}
class People{//構造People類
private String name;
private int age;
public People(String name, int age) {
super();
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;
}
@Override
public int hashCode() {//因為要儲存到HashSet中,所以需要覆蓋hashCode方法
//返回姓名+年齡的雜湊值。
return name.hashCode()+age*37;
}
@Override
public boolean equals(Object obj) {//在HashSet中,hashCode值相同比較equals方法
//如果比較的不是People物件,就返回不相等
if(!(obj instanceof People))
return false;
People p = (People)obj;//將obj轉成People
//比較姓名和年齡是否相等
return this.name.equals(p.name) && this.age == p.age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
//輸出結果:
a3::13
a1::11
a2::12
//通過執行結果可以反映出雜湊表中的儲存是無序的。
TreeSet
排序的第一種方式:讓元素自身具備比較性。元素需要實現Comparable介面,覆蓋compareTo方法。也種方式也成為元素的自然順序,或者叫做預設順序。
TreeSet的第二種排序方式。當元素自身不具備比較性時,或者具備的比較性不是所需要的。這時就需要讓集合自身具備比較性。在集合初始化時,就有了比較方式。,實現Comparator介面,覆蓋compare方法
package pract;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
//<Stu>是泛型。泛型格式:通過<>來定義要操作的引用資料型別。
TreeSet<Stu> ts = new TreeSet<Stu>(new MyCompare());
ts.add(new Stu("liming",12,80));
ts.add(new Stu("zhangsan",11,90));
ts.add(new Stu("lisi",20,70));
ts.add(new Stu("wangwu",18,100));
Iterator<Stu> it = ts.iterator();
while(it.hasNext()){
Stu stu = it.next();
System.out.println(stu);
}
}
}
class Stu implements Comparable<Stu>{//強制使Stu具備比較性
private String name;
private int age;
private int score;
public Stu(String name, int age, int score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
//實現compareTo方法,這個方法是按照年齡排序
public int compareTo(Stu s){
int num = new Integer(this.age).compareTo(s.age);
if(num==0)
num = this.name.compareTo(s.name);
return num;
}
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 int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
//我們以後定義類應該複寫hashCode和equals方法,保證類在雜湊表中也可以正確儲存。
public int hashCode() {
return name.hashCode()+age*37;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Stu))
return false;
Stu s = (Stu)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
@Override
public String toString() {
return "Stu [name=" + name + ", age=" + age + ", score=" + score + "]";
}
}
class MyCompare implements Comparator<Stu>{//自定義比較器,按照姓名排序,姓名相同按照年齡排序
public int compare(Stu s1,Stu s2){
int num = s1.getName().compareTo(s2.getName());
if(num==0){
num = new Integer(s1.getAge()).compareTo(s2.getAge());
}
return num;
}
}
//執行結果:
Stu [name=liming, age=12, score=80]
Stu [name=lisi, age=20, score=70]
Stu [name=wangwu, age=18, score=100]
Stu [name=zhangsan, age=11, score=90]
//分析,果然按照姓名排序了。
泛型好處
1.將執行時期出現問題ClassCastException,轉移到了編譯時期。,
方便於程式設計師解決問題。讓執行時問題減少,安全。,
2,避免了強制轉換麻煩。
泛型格式:通過<>來定義要操作的引用資料型別。
當泛型定義在方法上時候放在返回值前面。
3,什麼時候定義泛型類?
當類中要操作的引用資料型別不確定的時候,早期定義Object來完成擴充套件。現在定義泛型來完成擴充套件。
泛型可以定義在類上,方法上,介面上,還可以定義在靜態方法上:
如果靜態方法操作的應用資料型別不確定,可以將泛型定義在方法上。
package pract;
public 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 t)//泛型定義在靜態方法上
{
System.out.println("method:"+t);
}
//靜態方法不可以訪問類上定義的泛型。但是可以把泛型定義在方法上。
public static void main(String[] args) {
Demo<String> d = new Demo<String>();
d.show("java");
d.print(434);
d.method("static");
}
}
//執行結果:
show:java
print:434
method:static