Java集合

1.Collection接口

1.1介紹

英文名稱(chēng)Collection,是用來(lái)存放對(duì)象的數(shù)據(jù)結(jié)構(gòu)。其中長(zhǎng)度可變,而且集合中可以存放不同類(lèi)型的對(duì)象。并提供了一組操作成批對(duì)象的方法。
數(shù)組的缺點(diǎn):長(zhǎng)度是固定不可變的,訪問(wèn)方式單一,插入、刪除等操作繁瑣。

1.2 集合的繼承結(jié)構(gòu)

1.3 常用方法測(cè)試

package cn.tedu.collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
//這個(gè)類(lèi)用來(lái)測(cè)試Collection接口
public class Test1_Collection {
    public static void main(String[] args) {
       //1,創(chuàng)建Collection接口對(duì)象
//     Collection c = new Collection();//報(bào)錯(cuò),因?yàn)镃ollection是接口不能new
       //a,<Integer>是泛型,用來(lái)約束集合中元素的類(lèi)型,只能寫(xiě)引用類(lèi)型不能是基本類(lèi)型
       Collection<Integer> c = new ArrayList();
       //2,常用方法
       c.add(100);//添加元素
       c.add(200);
       c.add(300);
       System.out.println(c);
//     c.clear();//清空集合
       System.out.println( c.contains(300) );//判斷集合是否包含指定元素
       System.out.println( c.equals(100) );//判斷和100是否相等
       System.out.println( c.hashCode() );//返回集合的哈希碼值
       System.out.println( c.isEmpty() );//判斷集合是否為空
       System.out.println( c.remove(200) );//判斷是否成功刪除集合中的元素
       System.out.println( c.size() );//獲取集合的長(zhǎng)度/個(gè)數(shù)
       Object[] os = c.toArray();//把集合的元素放入數(shù)組
       System.out.println( Arrays.toString(os) );
       //集合間的操作
       Collection<Integer> c2 = new ArrayList();
       c2.add(9);
       c2.add(8);
       c2.add(7);
       c.addAll(c2);//把c2加到c里
       System.outprintln( c.containsAll(c2) );//判斷c中是否包含c2
       System.out.println( c.removeAll(c2) );//刪除c2
//     System.out.println( c.retainAll(c2) );//刪除c
       System.out.println(c);
       //用來(lái) 遍歷/迭代 集合中的元素Iterator<E> iterator() 
       Iterator<Integer> it = c.iterator();
       //通過(guò)Iterator迭代器,循環(huán)著獲取集合中的元素
       while(it.hasNext()) {
           //hasNext()用來(lái)判斷集合中是否有下個(gè)元素,有就返回true
           Integer inte = it.next();//next()獲取迭代到的元素
           System.out.println(inte);
       }
    }
}

2.List接口

2.1介紹

有序的 collection(也稱(chēng)為序列)。此接口的用戶(hù)可以對(duì)列表中每個(gè)元素的插入位置進(jìn)行精確地控制。用戶(hù)可以根據(jù)元素的整數(shù)索引(在列表中的位置)訪問(wèn)元素,并搜索列表中的元素。

2.2常用方法測(cè)試

package cn.tedu.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
//這個(gè)類(lèi)用測(cè)試List接口
public class Test2_List {
    public static void main(String[] args) {
       //1,創(chuàng)建List接口對(duì)象
       List<String> list = new ArrayList();
       //2,繼承自Collection接口的方法
       list.add("jack");//添加元素
       list.add("tony");
       list.add("hanmeimei");
       list.add("tony");
       list.add("tony");
       list.add("tony");
       list.clear();//清空集合
       System.out.println(  list.contains("jack") );
       System.out.println(  list.equals("jack") );
       System.out.println(  list.hashCode() );
       System.out.println(  list.isEmpty() );
       System.out.println(  list.remove("hanmeimei") );
       System.out.println(  list.size() );
       System.out.println(  list.toArray() );//變成數(shù)組
       //3,List接口的特有方法    --  都是可以按照索引來(lái)操作的方式
       list.add(1, "蔡徐坤");//在指定索引處添加指定的元素
       System.out.println(list+"===");
       System.out.println(list.get(2));//獲取下標(biāo)對(duì)應(yīng)的元素
       System.out.println(list.indexOf("tony"));//獲取指定元素第一次出現(xiàn)的下標(biāo)
       System.out.println(list.lastIndexOf("tony"));//獲取指定元素最后一次出現(xiàn)的下標(biāo)
       System.out.println(list.remove(3));//按照下標(biāo)刪除指定元素
       System.out.println(list.set(0,"xiongda"));//置換元素
       List<String> subList = list.subList(2, 4);//截取下標(biāo)2-4的元素(含頭不含尾)
       System.out.println(subList);
       //TODO 集合間的操作
       List<String> list2 = new ArrayList();
       list2.add("1");
       list2.add("2");
       list2.add("3");
       System.out.println(  list.addAll(list2));//把list2加到list里
       System.out.println(  list.addAll(1, list2));//在指定下標(biāo)處添加元素
       System.out.println(  list.contains(list2));//判斷是否包含
       System.out.println(  list.removeAll(list2));//刪除list2
       System.out.println(  list.retainAll(list2));//刪除list
       //TODO 集合的迭代  -- List集合的迭代方式有多種:
       //iterator()  listIterator()  for()  foreach
       //方式1:由于List集合有下標(biāo),所以可以根據(jù)下標(biāo)遍歷數(shù)據(jù)
              //i < list.size()  下標(biāo)最大值是集合長(zhǎng)度-1
       for(int i = 0 ; i < list.size() ; i++) {
           String s = list.get(i);//list.get(i)根據(jù)下標(biāo)獲取元素
           System.out.println(s);
       }
       //方式2:普通for循環(huán)遍歷的效率低,可以用foreach提高,好處:語(yǔ)法簡(jiǎn)潔效率高 壞處:不能按照下標(biāo)獲取
       //for(1 2:3){}  -- 3是要遍歷的數(shù)據(jù)   1是遍歷得到的數(shù)據(jù)的類(lèi)型   2是變量名
       for(String str:list) {
           System.out.println(str);//str代表的是當(dāng)前遍歷到的數(shù)據(jù)
       }
       //方式3:iterator() 是繼承自父接口Collection的
       Iterator<String> it = list.iterator();
       while(it.hasNext()) {//hasNext()判讀是否有下一個(gè)元素
           String str = it.next();//next()獲取元素
           System.out.println(str);//打印獲取到的值
       }
       //方式4:listIterator() 是List接口的特有方法
       //Iterator<E> iterator()  --父接口 --hasNext()  --next() --remove()
       //ListIterator<E> listIterator() --子接口,擁有父接口的方法,也有自己的特有方法(逆向迭代)
       //public interface ListIterator<E>  extends Iterator<E>
       ListIterator<String> it2 = list.listIterator();
       while(it2.hasNext()) {//hasNext()判斷后面有沒(méi)有數(shù)據(jù)
           String s = it2.next();//next()獲取后一個(gè)數(shù)據(jù)
           System.out.println(s);//打印獲取到的數(shù)據(jù)
       }
       //總結(jié):方式3和方式4有什么區(qū)別?-- 3是父接口Iterator4是子接口ListIterator
       //子接口擁有父接口的所有方法也有自己的特有方法,子接口的特有方法就是向前/逆向遍歷
    }
}

3.ArrayList實(shí)現(xiàn)類(lèi)

3.1介紹

1.存在于java.util包中。
2.內(nèi)部用數(shù)組存放數(shù)據(jù),封裝了數(shù)組的操作,每個(gè)對(duì)象都有下標(biāo)。
3.內(nèi)部數(shù)組默認(rèn)初始容量是10,如果不夠會(huì)以1.5倍容量增長(zhǎng)。
4.查詢(xún)快,增刪數(shù)據(jù)效率會(huì)降低。
ArrayList的用法和List一樣只是創(chuàng)建對(duì)象時(shí)用的是:

ArrayList<Integer> list = new ArrayList<>();

4.LinkedList實(shí)現(xiàn)類(lèi)

4.1介紹

雙向鏈表,兩端效率高,下標(biāo)遍歷效率低,迭代器遍歷效率高。底層就是數(shù)組和鏈表實(shí)現(xiàn)的。


4.2常用方法測(cè)試

package cn.tedu.collection;
import java.util.LinkedList;
//這個(gè)類(lèi)用來(lái)測(cè)試LinkedList
public class Test4_LinkedList {
    public static void main(String[] args) {
       //1,創(chuàng)建對(duì)象
       LinkedList<String>  list = new LinkedList();
       //2,常用方法
       list.add("杰克");
       list.add("肉絲");
       list.add("凹凸曼");
       list.add("蜘蛛俠");
       System.out.println(list);
       //3,LinkedList特有方法
       list.addFirst("美隊(duì)");//添加首元素
       list.addLast("鋼鐵俠");//添加尾元素
       System.out.println(list);
       System.out.println( list.getFirst());//獲取首元素
       System.out.println( list.getLast());//獲取尾元素
       System.out.println(  list.removeFirst());//刪除首元素
       System.out.println(  list.removeLast());//刪除尾元素
    }
}

5.Set接口

5.1介紹

一個(gè)不包含重復(fù)元素的 collection。數(shù)據(jù)無(wú)序(因?yàn)閟et集合沒(méi)有下標(biāo))。由于集合中的元素不可以重復(fù)。常用于給數(shù)據(jù)去重。HashSet:底層是哈希表。TreeSet:底層是TreeMap,也是紅黑樹(shù)的形式,便于查找數(shù)據(jù)。

5.2常用方法測(cè)試

package cn.tedu.collection;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
//這個(gè)類(lèi)用來(lái)測(cè)試Set接口的用法
public class Test5_Set {
    public static void main(String[] args) {
       //1,創(chuàng)建Set對(duì)象 
//     Set set = new Set();//報(bào)錯(cuò),因?yàn)镾et是接口,不能new
       Set<String> set = new HashSet();
       //2,常用方法 
       set.add("jack");
       set.add("rose");
       set.add("tony");
       set.add("hanmeimei");
       set.add("tony");
       set.add("null");
       System.out.println(set);
       set.clear();//清空集合
       System.out.println(set.contains("tony"));//判斷set中是否包含元素
       System.out.println(set.equals("tony"));//判斷set是否和tony相等
       System.out.println(set.hashCode());//獲取set集合的哈希碼值
       System.out.println(set.isEmpty());//判斷set集合是否為空
       System.out.println(set.remove("null"));//刪除集合的指定元素
       System.out.println(set.size());//獲取集合的長(zhǎng)度
       Object[] obs = set.toArray();//把集合的元素放入數(shù)組中
       System.out.println(Arrays.toString(obs));//查看數(shù)組里的元素值
       //集合間的操作
       Set<String> set2 = new HashSet();
       set2.add("1");
       set2.add("2");
       set2.add("3");
       System.out.println(set.addAll(set2));//把set2加入到set中
       System.out.println(set.containsAll(set2));//判斷set中是否包含set2
       System.out.println(set.removeAll(set2));//刪除set2
       System.out.println(set.retainAll(set2));//刪除set
       //集合的迭代Iterator<E> iterator()
       Iterator<String> it = set.iterator();
       while(it.hasNext()) {//判斷有沒(méi)有下一個(gè)元素
           String s = it.next();//獲取元素
           System.out.println(s);//打印獲取到的元素
       }
    }
}

6.HashSet實(shí)現(xiàn)類(lèi)

6.1介紹

底層是哈希表,包裝了HashMap,相當(dāng)于向HashSet中存入數(shù)據(jù)時(shí),會(huì)把數(shù)據(jù)作為K,存入內(nèi)部的HashMap中。其中,K不許重復(fù)。此類(lèi)允許使用 null 元素。
HashSet的方法用法和Set一樣只是創(chuàng)建對(duì)象時(shí)用的是:

HashSet<Integer> set = new HashSet();

7.Set給自定義對(duì)象去重

Set集合去重原理:Set集合去重主要是調(diào)用 add 方法時(shí),使用了 hashCode 方法和equals 方法,如果在 Set集合 中找不到與該元素 hashCode 值相同的元素,則說(shuō)明該元素是新元素,會(huì)被添加到 Set 集合中;如果兩個(gè)元素的 hashCode 值相同,并且使用 equals 方法比較后,返回值為 true,那么就說(shuō)明兩個(gè)元素相同,新元素不會(huì)被添加到 Set 集合中;如果 hashCode 值相同,但是 equals 方法比較后,返回值為 false ,則兩個(gè)元素不相同,新元素會(huì)被添加到 Set 集合中。
創(chuàng)建學(xué)生類(lèi)

package cn.tedu.collection;
//這個(gè)類(lèi)用來(lái)測(cè)試set給自定義對(duì)象去重
public class Student {
    //提供構(gòu)造方法
    public Student() {}
    public Student(String name, int age, String addr) {
       super();
       this.name = name;
       this.age = age;
       this.addr = addr;
    }

    //提供私有屬性
    private String name;
    private int age;
    private String addr;

    //提供set()/get()方法
    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 getAddr() {
       return addr;
    }
    public void setAddr(String addr) {
       this.addr = addr;
    }

    //重寫(xiě)toString()
    @Override
    public String toString() {
       return "Student [name=" + name + ", age=" + age + ", addr=" + addr + "]";
    }

    //重寫(xiě)hashCode():想要根據(jù)兩個(gè)對(duì)象的屬性值計(jì)算哈希值,
    //如果屬性值完全都一樣,就保證產(chǎn)生的hash值也一樣
    @Override
    public int hashCode() {
       final int prime = 31;
       int result = 1;
       result = prime * result + ((addr == null) ? 0 : addr.hashCode());
       result = prime * result + age;
       result = prime * result + ((name == null) ? 0 : name.hashCode());
       return result;
    }

    //重寫(xiě)equals():要比較對(duì)象間的屬性值,如果屬性值都一樣,返回true
    @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 (addr == null) {
           if (other.addr != null)
              return false;
       } else if (!addr.equals(other.addr))
           return false;
       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;
    }
}

測(cè)試

package cn.tedu.collection;
import java.util.HashSet;
import java.util.Set;
//這個(gè)類(lèi)用來(lái)給自定義對(duì)象去重
//總結(jié):
//1、如果你想用Set集合,給自定義對(duì)象去重,要求你在自己的類(lèi)中,同時(shí)提供重寫(xiě)的hashCode()和equals()
//--源碼摘抄:if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))
//重寫(xiě)的hashCode():我們不適用默認(rèn)的自動(dòng)計(jì)算出來(lái)的哈希值,而是要根據(jù)對(duì)象的屬性值計(jì)算,如果對(duì)象的屬性值都相同,那么請(qǐng)產(chǎn)生相同的哈希值
//重寫(xiě)的equals():我們要比較的不是對(duì)象的地址值,而是比較,兩個(gè)對(duì)象間如果屬性值都一樣就返回true
public class Test7_HashSet2 {
    public static void main(String[] args) {
       //1,創(chuàng)建Set集合對(duì)象
       Set<Student> set = new HashSet<Student>();
       //2,向set集合中添加自定義對(duì)象
       Student s1 = new Student("tony",20,"BJ");
       Student s2 = new Student("jack",10,"SH");
       Student s3 = new Student("rose",30,"SH");
       Student s4 = new Student("jack",10,"SH");
       Student s5 = new Student("rose",30,"SH");
       set.add(s1);
       set.add(s2);
       set.add(s3);
       //重復(fù)的添加了屬性相同的對(duì)象,為什么沒(méi)有去重??
       //1,保證對(duì)象擁有相同的哈希值??默認(rèn)使用的是Object提供的hashCode()計(jì)算的哈希值
       //如果你想要根據(jù)兩個(gè)對(duì)象的屬性值計(jì)算哈希值,那就需要重寫(xiě)hashCode()
       //2,是要保證兩個(gè)對(duì)象間的equals()返回true,那就需要重寫(xiě)equals()
       set.add(s4);
       set.add(s5);
       System.out.println(set);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容