java集合總結(jié)

今天在看了好多個(gè)集合帖子后發(fā)現(xiàn)講的都是一半一半的,這下就逼死我這個(gè)強(qiáng)迫癥患者了.于是自己寫(xiě)點(diǎn),有不足之處還望各位道友多多指點(diǎn)

一、Collection接口

1.Collection接口

1.java.util.Collection接口:

1.所有單列集合的最頂層的接口,里邊定義了所有單列集合共性的方法
2.任意的單列集合都可以使用Collection接口中的方法

共性的方法:

 public boolean add(E e):  把給定的對(duì)象添加到當(dāng)前集合中 。
 public void clear() :清空集合中所有的元素悔耘。
 public boolean remove(E e): 把給定的對(duì)象在當(dāng)前集合中刪除扛吞。
 public boolean contains(E e): 判斷當(dāng)前集合中是否包含給定的對(duì)象伊约。
 public boolean isEmpty(): 判斷當(dāng)前集合是否為空撕瞧。
 public int size(): 返回集合中元素的個(gè)數(shù)尤蛮。
 public Object[] toArray(): 把集合中的元素县匠,存儲(chǔ)到數(shù)組中风科。

示例

public class Collection {
    public static void main(String[] args) {
        //創(chuàng)建集合對(duì)象,可以使用多態(tài)
        //Collection<String> coll = new ArrayList<>();
        Collection<String> coll = new HashSet<>();
        System.out.println(coll);//重寫(xiě)了toString方法  []
?
        /*
            public boolean add(E e):把給定的對(duì)象添加到當(dāng)前集合中 。
            返回值是一個(gè)boolean值,一般都返回true,所以可以不用接收
         */
        boolean b1 = coll.add("張三");
        System.out.println("b1:"+b1);//b1:true
        System.out.println(coll);//[張三]
        coll.add("李四");
        coll.add("李四");
        coll.add("趙六");
        coll.add("田七");
        System.out.println(coll);//[張三, 李四, 趙六, 田七]
?
        /*
            public boolean remove(E e): 把給定的對(duì)象在當(dāng)前集合中刪除乞旦。
            返回值是一個(gè)boolean值,集合中存在元素,刪除元素,返回true
                                集合中不存在元素,刪除失敗,返回false
         */
        boolean b2 = coll.remove("趙六");
        System.out.println("b2:"+b2);//b2:true
?
        boolean b3 = coll.remove("趙四");
        System.out.println("b3:"+b3);//b3:false
        System.out.println(coll);//[張三, 李四, 田七]
?
        /*
            public boolean contains(E e): 判斷當(dāng)前集合中是否包含給定的對(duì)象丐重。
            包含返回true
            不包含返回false
         */
        boolean b4 = coll.contains("李四");
        System.out.println("b4:"+b4);//b4:true
?
        boolean b5 = coll.contains("趙四");
        System.out.println("b5:"+b5);//b5:false
?
        //public boolean isEmpty(): 判斷當(dāng)前集合是否為空。集合為空返回true,集合不為空返回false
        boolean b6 = coll.isEmpty();
        System.out.println("b6:"+b6);//b6:false
?
        //public int size(): 返回集合中元素的個(gè)數(shù)杆查。
        int size = coll.size();
        System.out.println("size:"+size);//size:3
?
        //public Object[] toArray(): 把集合中的元素扮惦,存儲(chǔ)到數(shù)組中。
        Object[] arr = coll.toArray();
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
?
        //public void clear() :清空集合中所有的元素亲桦。但是不刪除集合,集合還存在
        coll.clear();
        System.out.println(coll);//[]
        System.out.println(coll.isEmpty());//true
    }
}

2.Collection工具類(lèi)

java.utils.Collections是集合工具類(lèi)崖蜜,用來(lái)對(duì)集合進(jìn)行操作。部分方法如下:

public static <T> boolean addAll(Collection<T> c, T...
elements):往集合中添加一些元素客峭。
public static void shuffle(List<?> list) :打亂順序:打亂集合順序豫领。

示例

?public class Collections {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        //往集合中添加多個(gè)元素
        /*list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");*/
?
        //public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。
        Collections.addAll(list,"a","b","c","d","e");
?
        System.out.println(list);//[a, b, c, d, e]
?
        //public static void shuffle(List<?> list) 打亂順序:打亂集合順序舔琅。
        Collections.shuffle(list);
        System.out.println(list);//[b, d, c, a, e], [b, d, c, a, e]
    }
}

public static void sort(List list):將集合中元素按照默認(rèn)規(guī)則排序等恐。
注意:
sort(List list)使用前提:
被排序的集合里邊存儲(chǔ)的元素,必須實(shí)現(xiàn)Comparable,重寫(xiě)接口中的方法compareTo定義排序的規(guī)則
?

public class Sort {
    public static void main(String[] args) {
        ArrayList<Integer> list01 = new ArrayList<>();
        list01.add(1);
        list01.add(3);
        list01.add(2);
        System.out.println(list01);//[1, 3, 2]
?
        //public static <T> void sort(List<T> list):將集合中元素按照默認(rèn)規(guī)則排序。
        Collections.sort(list01);//默認(rèn)是升序
?
        System.out.println(list01);//[1, 2, 3]
?
        ArrayList<String> list02 = new ArrayList<>();
        list02.add("a");
        list02.add("c");
        list02.add("b");
        System.out.println(list02);//[a, c, b]
?
        Collections.sort(list02);
        System.out.println(list02);//[a, b, c]
?
        ArrayList<Person> list03 = new ArrayList<>();
        list03.add(new Person("張三",18));
        list03.add(new Person("李四",20));
        list03.add(new Person("王五",15));
        System.out.println(list03);//[Person{name='張三', age=18}, Person{name='李四', age=20}, Person{name='王五', age=15}]
?
        Collections.sort(list03);
        System.out.println(list03);
    }
}

Comparator和Comparable的區(qū)別
Comparable:自己(this)和別人(參數(shù))比較,自己需要實(shí)現(xiàn)Comparable接口,重寫(xiě)比較的規(guī)則compareTo方法
Comparator:相當(dāng)于找一個(gè)第三方的裁判,比較兩個(gè)
Comparable接口位于java.lang包下备蚓;Comparator位于java.util包下 Comparable接口只提供了一個(gè)compareTo()方法课蔬;Comparator接口不僅提供了compara()方法,還提供了其他默認(rèn)方法郊尝,如reversed()二跋、thenComparing(),使我們可以按照更多的方式進(jìn)行排序

如果要用Comparable接口流昏,則必須實(shí)現(xiàn)這個(gè)接口扎即,并重寫(xiě)comparaTo()方法吞获;但是Comparator接口可以在類(lèi)外部使用,通過(guò)將該接口的一個(gè)匿名類(lèi)對(duì)象當(dāng)做參數(shù)傳遞給Collections.sort()方法或者Arrays.sort()方法實(shí)現(xiàn)排序谚鄙。Comparator體現(xiàn)了一種策略模式各拷,即可以不用要把比較方法嵌入到類(lèi)中,而是可以單獨(dú)在類(lèi)外部使用闷营,這樣我們就可有不用改變類(lèi)本身的代碼而實(shí)現(xiàn)對(duì)類(lèi)對(duì)象進(jìn)行排序烤黍。
Comparator的排序規(guī)則:
o1-o2:升序

public class Sort2 {
    public static void main(String[] args) {
?        ArrayList<Integer> list01 = new ArrayList<>();
        list01.add(1);
        list01.add(3);
        list01.add(2);
        System.out.println(list01);//[1, 3, 2]
?
        Collections.sort(list01, new Comparator<Integer>() {
            //重寫(xiě)比較的規(guī)則
            @Override
            public int compare(Integer o1, Integer o2) {
                //return o1-o2;//升序
                return o2-o1;//降序
            }
        });
?
        System.out.println(list01);
?
        ArrayList<Student> list02 = new ArrayList<>();
        list02.add(new Student("李志",18));
        list02.add(new Student("李德軒",20));
        list02.add(new Student("方永泰",17));
        list02.add(new Student("段睿新",18));
        System.out.println(list02);
?
        /*Collections.sort(list02, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //按照年齡升序排序
                return o1.getAge()-o2.getAge();
            }
        });*/
?
        //擴(kuò)展:了解
        Collections.sort(list02, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //按照年齡升序排序
                int result =  o1.getAge()-o2.getAge();
                //如果兩個(gè)人年齡相同,再使用姓名的第一個(gè)字比較
                if(result==0){
                    result =  o1.getName().charAt(0)-o2.getName().charAt(0);
                }
                return  result;
            }
?
        });
?
        System.out.println(list02);
    }
}
public class Person implements Comparable<Person>{
    private String name;
    private int age; ?
    public Person() {
    } ?
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    } ?
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", 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;
    } ?
    //重寫(xiě)排序的規(guī)則
    @Override
    public int compareTo(Person o) {
        //return 0;//認(rèn)為元素都是相同的
        //自定義比較的規(guī)則,比較兩個(gè)人的年齡(this,參數(shù)Person)
        //return this.getAge() - o.getAge();//年齡升序排序
        return o.getAge() - this.getAge();//年齡升序排序
    } }
public class Student {
    private String name;
    private int age;
?
    public Student() {
    }
?
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
?
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", 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;
    }
}

二、Iterator迭代器粮坞、增強(qiáng)for循環(huán)蚊荣、泛型

1.Iterator迭代器

java.util.Iterator接口:迭代器(對(duì)集合進(jìn)行遍歷)

常用的方法

boolean hasNext() 如果仍有元素可以迭代,則返回 true莫杈。
判斷集合中還有沒(méi)有下一個(gè)元素,有就返回true,沒(méi)有就返回false E next() 返回迭代的下一個(gè)元素互例。取出集合中的下一個(gè)元素

**注意:**

Iterator迭代器,是一個(gè)接口,我們無(wú)法直接使用,需要使用Iterator接口的實(shí)現(xiàn)類(lèi)對(duì)象,獲取實(shí)現(xiàn)類(lèi)的方式比較特殊
Collection接口中有一個(gè)方法,叫iterator(),這個(gè)方法返回的就是迭代器的實(shí)現(xiàn)類(lèi)對(duì)象
Iterator<E> iterator() 返回在此 collection 的元素上進(jìn)行迭代的迭代器

迭代器的使用步驟(重點(diǎn)):

1.使用集合中的方法iterator()獲取迭代器的實(shí)現(xiàn)類(lèi)對(duì)象,使用Iterator接口接收(多態(tài))
2.使用Iterator接口中的方法hasNext判斷還有沒(méi)有下一個(gè)元素
3.使用Iterator接口中的方法next取出集合中的下一個(gè)元素

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
?
public class Iterator {
    public static void main(String[] args) {
        //創(chuàng)建一個(gè)集合對(duì)象
        Collection<String> coll = new ArrayList<>();
        //往集合中添加元素
        coll.add("姚明");
        coll.add("科比");
        coll.add("麥迪");
        coll.add("詹姆斯");
        coll.add("艾弗森");
?
        /*
            1.使用集合中的方法iterator()獲取迭代器的實(shí)現(xiàn)類(lèi)對(duì)象,使用Iterator接口接收(多態(tài))
            注意:
                Iterator<E>接口也是有泛型的,迭代器的泛型跟著集合走,集合是什么泛型,迭代器就是什么泛型
         */
        //多態(tài)  接口            實(shí)現(xiàn)類(lèi)對(duì)象
        Iterator<String> it = coll.iterator();
?
?
        /*
            發(fā)現(xiàn)使用迭代器取出集合中元素的代碼,是一個(gè)重復(fù)的過(guò)程
            所以我們可以使用循環(huán)優(yōu)化
            不知道集合中有多少元素,使用while循環(huán)
            循環(huán)結(jié)束的條件,hasNext方法返回false
         */
        while(it.hasNext()){
            String e = it.next();
            System.out.println(e);
        }
        System.out.println("----------------------");
        for(Iterator<String> it2 = coll.iterator();it2.hasNext();){
            String e = it2.next();
            System.out.println(e);
        }
?
?
       /* //2.使用Iterator接口中的方法hasNext判斷還有沒(méi)有下一個(gè)元素
        boolean b = it.hasNext();
        System.out.println(b);//true
        //3.使用Iterator接口中的方法next取出集合中的下一個(gè)元素
        String s = it.next();
        System.out.println(s);//姚明
?
        b = it.hasNext();
        System.out.println(b);
        s = it.next();
        System.out.println(s);
?
        b = it.hasNext();
        System.out.println(b);
        s = it.next();
        System.out.println(s);
?
        b = it.hasNext();
        System.out.println(b);
        s = it.next();
        System.out.println(s);
        b = it.hasNext();
        System.out.println(b);
        s = it.next();
        System.out.println(s);
?
        b = it.hasNext();
        System.out.println(b);//沒(méi)有元素,返回false
        s = it.next();//沒(méi)有元素,在取出元素會(huì)拋出NoSuchElementException沒(méi)有元素異常
        System.out.println(s);*/
    }
}

2.增強(qiáng)for循環(huán)

增強(qiáng)for循環(huán):底層使用的也是迭代器,使用for循環(huán)的格式,簡(jiǎn)化了迭代器的書(shū)寫(xiě) 是JDK1.5之后出現(xiàn)的新特性
Collectionextends Iterable:所有的單列集合都可以使用增強(qiáng)for public interface
Iterable實(shí)現(xiàn)這個(gè)接口允許對(duì)象成為 “foreach” 語(yǔ)句的目標(biāo)。
增強(qiáng)for循環(huán):用來(lái)遍歷集合和數(shù)組 格式:
for(集合/數(shù)組的數(shù)據(jù)類(lèi)型 變量名: 集合名/數(shù)組名){ sout(變量名); }

import java.util.ArrayList;
public class Foreach {
    public static void main(String[] args) {
        demo02();
    }
?
    //使用增強(qiáng)for循環(huán)遍歷集合
    private static void demo02() {
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        for(String s : list){
            System.out.println(s);
        }
    }
?
    //使用增強(qiáng)for循環(huán)遍歷數(shù)組
    private static void demo01() {
        int[] arr = {1,2,3,4,5};
        for(int i:arr){
            System.out.println(i);
        }
    }
}

3.泛型

import java.util.ArrayList;
import java.util.Iterator;
?
public class Generic {
    public static void main(String[] args) {
        show02();
    }
?
    /*
        創(chuàng)建集合對(duì)象,使用泛型
        好處:
            1.避免了類(lèi)型轉(zhuǎn)換的麻煩,存儲(chǔ)的是什么類(lèi)型,取出的就是什么類(lèi)型
            2.把運(yùn)行期異常(代碼運(yùn)行之后會(huì)拋出的異常),提升到了編譯期(寫(xiě)代碼的時(shí)候會(huì)報(bào)錯(cuò))
         弊端:
            泛型是什么類(lèi)型,只能存儲(chǔ)什么類(lèi)型的數(shù)據(jù)
     */
    private static void show02() {
        ArrayList<String> list = new ArrayList<>();
        list.add("abc");
        //list.add(1);//add(java.lang.String)in ArrayList cannot be applied to (int)
?
        //使用迭代器遍歷list集合
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String s = it.next();
            System.out.println(s+"->"+s.length());
        }
    }
?
    /*
        創(chuàng)建集合對(duì)象,不使用泛型
        好處:
            集合不使用泛型,默認(rèn)的類(lèi)型就是Object類(lèi)型,可以存儲(chǔ)任意類(lèi)型的數(shù)據(jù)
        弊端:
            不安全,會(huì)引發(fā)異常
     */
    private static void show01() {
        ArrayList list = new ArrayList();
        list.add("abc");
        list.add(1);
?
        //使用迭代器遍歷list集合
        //獲取迭代器
        Iterator it = list.iterator();
        //使用迭代器中的方法hasNext和next遍歷集合
        while(it.hasNext()){
            //取出元素也是Object類(lèi)型
            Object obj = it.next();
            System.out.println(obj);
?
            //想要使用String類(lèi)特有的方法,length獲取字符串的長(zhǎng)度;不能使用  多態(tài) Object obj = "abc";
            //需要向下轉(zhuǎn)型
            //會(huì)拋出ClassCastException類(lèi)型轉(zhuǎn)換異常,不能把Integer類(lèi)型轉(zhuǎn)換為String類(lèi)型
            String s = (String)obj;
            System.out.println(s.length());
        }
    }
}

①定義含有泛型的類(lèi)

模擬ArrayList集合

泛型是一個(gè)未知的數(shù)據(jù)類(lèi)型,當(dāng)我們不確定什么什么數(shù)據(jù)類(lèi)型的時(shí)候,可以使用泛型
泛型可以接收任意的數(shù)據(jù)類(lèi)型,可以使用Integer,String,Student... 創(chuàng)建對(duì)象的時(shí)候確定泛型的數(shù)據(jù)類(lèi)型

public class GenericClass<E> {
    private E name;
?
    public E getName() {
        return name;
    }
?
    public void setName(E name) {
        this.name = name;
    }
}
public class GenericClass {
    public static void main(String[] args) {
        //不寫(xiě)泛型默認(rèn)為Object類(lèi)型
        GenericClass gc = new GenericClass();
        gc.setName("只能是字符串");
        Object obj = gc.getName(); ?
        //創(chuàng)建GenericClass對(duì)象,泛型使用Integer類(lèi)型
        GenericClass<Integer> gc2 = new GenericClass<>();
        gc2.setName(1); ?
        Integer name = gc2.getName();
        System.out.println(name); ?
        //創(chuàng)建GenericClass對(duì)象,泛型使用String類(lèi)型
        GenericClass<String> gc3 = new GenericClass<>();
        gc3.setName("小明");
        String name1 = gc3.getName();
        System.out.println(name1);
    } }

②定義含有泛型的方法

泛型定義在方法的修飾符和返回值類(lèi)型之間

格式:
修飾符 <泛型> 返回值類(lèi)型 方法名(參數(shù)列表(使用泛型)){
方法體;
}

含有泛型的方法,在調(diào)用方法的時(shí)候確定泛型的數(shù)據(jù)類(lèi)型 傳遞什么類(lèi)型的參數(shù),泛型就是什么類(lèi)型

public class GenericMethod {
    //定義一個(gè)含有泛型的方法
    public <M> void method01(M m){
        System.out.println(m);
    }
?
    //定義一個(gè)含有泛型的靜態(tài)方法
    public static <S> void method02(S s){
        System.out.println(s);
    }
}

測(cè)試含有泛型的方法

public class DemoGenericMethod {
    public static void main(String[] args) {
        //創(chuàng)建GenericMethod對(duì)象
        GenericMethod gm = new GenericMethod();
        /*
            調(diào)用含有泛型的方法method01
            傳遞什么類(lèi)型,泛型就是什么類(lèi)型
         */
        gm.method01(10);
        gm.method01("abc");
        gm.method01(8.8);
        gm.method01(true);
        gm.method02("靜態(tài)方法,不建議創(chuàng)建對(duì)象使用");
        //靜態(tài)方法,通過(guò)類(lèi)名.方法名(參數(shù))可以直接使用
        GenericMethod.method02("靜態(tài)方法");
        GenericMethod.method02(1);
    }
}

定義含有泛型的接口

public interface GenericInterface<I> {
    public abstract void method(I i);
}

③定義含有泛型的接口的實(shí)現(xiàn)類(lèi)

含有泛型的接口,第一種使用方式:定義接口的實(shí)現(xiàn)類(lèi),實(shí)現(xiàn)接口,指定接口的泛型 public interface Iterator<E> {
E next(); } Scanner類(lèi)實(shí)現(xiàn)了Iterator接口,并指定接口的泛型為String,所以重寫(xiě)的next方法泛型默認(rèn)就是String

public final class Scanner implements Iterator<String>{
    public String next() {}
}
public class GenericInterfaceImpl1 implements GenericInterface<String>{
    @Override
    public void method(String s) {
        System.out.println(s);
    }
}

含有泛型的接口第二種使用方式:接口使用什么泛型,實(shí)現(xiàn)類(lèi)就使用什么泛型,類(lèi)跟著接口走
就相當(dāng)于定義了一個(gè)含有泛型的類(lèi),創(chuàng)建對(duì)象的時(shí)候確定泛型的類(lèi)型

public interface List<E>{
    boolean add(E e);
    E get(int index);
}
public class ArrayList<E> implements List<E>{
    public boolean add(E e) {}
    public E get(int index) {}
}
public class GenericInterfaceImpl2<I> implements GenericInterface<I> {
    @Override
    public void method(I i) {
        System.out.println(i);
    }
}

測(cè)試含有泛型的接口

public class Demo04GenericInterface {
    public static void main(String[] args) {
        //創(chuàng)建GenericInterfaceImpl1對(duì)象
        GenericInterfaceImpl1 gi1 = new GenericInterfaceImpl1();
        gi1.method("字符串");
?
        //創(chuàng)建GenericInterfaceImpl2對(duì)象
        GenericInterfaceImpl2<Integer> gi2 = new GenericInterfaceImpl2<>();
        gi2.method(10);
?
        GenericInterfaceImpl2<Double> gi3 = new GenericInterfaceImpl2<>();
        gi3.method(8.8);
    }
}

④泛型標(biāo)識(shí)符

泛型的通配符:
?:代表任意的數(shù)據(jù)類(lèi)型 使用方式:
不能創(chuàng)建對(duì)象使用
只能作為方法的參數(shù)使用 泛型的上限限定: ? extends E 代表使用的泛型只能是E類(lèi)型的子類(lèi)/本身 泛型的下限限定: ? super E 代表使用的泛型只能是E類(lèi)型的父類(lèi)/本身

public class Demo05Generic {
    public static void main(String[] args) {
        ArrayList<Integer> list01 = new ArrayList<>();
        list01.add(1);
        list01.add(2);
?
        ArrayList<String> list02 = new ArrayList<>();
        list02.add("a");
        list02.add("b");
?
        printArray(list01);
        printArray(list02);
?
        //ArrayList<?> list03 = new ArrayList<?>();
    }
?
    /*
        定義一個(gè)方法,能遍歷所有類(lèi)型的ArrayList集合
        這時(shí)候我們不知道ArrayList集合使用什么數(shù)據(jù)類(lèi)型,可以泛型的通配符?來(lái)接收數(shù)據(jù)類(lèi)型
        注意:
            泛型沒(méi)有繼承概念的
     */
    public static void printArray(ArrayList<?> list){
        //使用迭代器遍歷集合
        Iterator<?> it = list.iterator();
        while(it.hasNext()){
            //it.next()方法,取出的元素是Object,可以接收任意的數(shù)據(jù)類(lèi)型
            Object o = it.next();
            System.out.println(o);
        }
    }
}
import java.util.ArrayList;
import java.util.Collection;
?
/*
    泛型的上限限定: ? extends E  代表使用的泛型只能是E類(lèi)型的子類(lèi)/本身
    泛型的下限限定: ? super E    代表使用的泛型只能是E類(lèi)型的父類(lèi)/本身
 */
public class Demo06Generic {
    public static void main(String[] args) {
        Collection<Integer> list1 = new ArrayList<Integer>();
        Collection<String> list2 = new ArrayList<String>();
        Collection<Number> list3 = new ArrayList<Number>();
        Collection<Object> list4 = new ArrayList<Object>();
?
        getElement1(list1);
        //getElement1(list2);//報(bào)錯(cuò)
        getElement1(list3);
        //getElement1(list4);//報(bào)錯(cuò)
?
        //getElement2(list1);//報(bào)錯(cuò)
        //getElement2(list2);//報(bào)錯(cuò)
        getElement2(list3);
        getElement2(list4);
?
        /*
            類(lèi)與類(lèi)之間的繼承關(guān)系
            Integer extends Number extends Object
            String extends Object
         */
?
    }
    // 泛型的上限:此時(shí)的泛型?筝闹,必須是Number類(lèi)型或者Number類(lèi)型的子類(lèi)
    public static void getElement1(Collection<? extends Number> coll){}
    // 泛型的下限:此時(shí)的泛型?媳叨,必須是Number類(lèi)型或者Number類(lèi)型的父類(lèi)
    public static void getElement2(Collection<? super Number> coll){}
}

三、幾種數(shù)據(jù)結(jié)構(gòu)的簡(jiǎn)單圖解

樹(shù)結(jié)構(gòu)

LInkdeLIst
ArrayList

彈棧壓棧

隊(duì)列

四关顷、幾種集合的介紹與使用方法

1.List集合

①ArrayList集合

java.util.List接口 extends Collection接口

List接口的特點(diǎn):

1.有序的集合,存儲(chǔ)元素和取出元素的順序是一致的(存儲(chǔ)123 取出123)
2.有索引,包含了一些帶索引的方法
?3.允許存儲(chǔ)重復(fù)的元素

List接口中帶索引的方法(特有)
- public void add(int index, E element): 將指定的元素糊秆,添加到該集合中的指定位置上。
- public E get(int index):返回集合中指定位置的元素议双。
- public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素痘番。
- public E set(int index, E element):用指定元素替換集合中指定位置的元素,返回值的更新前的元素。

注意:

操作索引的時(shí)候,一定要防止索引越界異常
IndexOutOfBoundsException:索引越界異常,集合會(huì)報(bào)
ArrayIndexOutOfBoundsException:數(shù)組索引越界異常
StringIndexOutOfBoundsException:字符串索引越界異常

public class List {
    public static void main(String[] args) {
        //創(chuàng)建一個(gè)List集合對(duì)象,多態(tài)
        List<String> list = new ArrayList<>();
        //使用add方法往集合中添加元素
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("a");
        //打印集合
        System.out.println(list);//[a, b, c, d, a]  不是地址重寫(xiě)了toString
?
        //public void add(int index, E element): 將指定的元素平痰,添加到該集合中的指定位置上汞舱。
        //在c和d之間添加一個(gè)itheima
        list.add(3,"itheima");//[a, b, c, itheima, d, a]
        System.out.println(list);
?
        //public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
        //移除元素
        String removeE = list.remove(2);
        System.out.println("被移除的元素:"+removeE);//被移除的元素:c
        System.out.println(list);//[a, b, itheima, d, a]
?
        //public E set(int index, E element):用指定元素替換集合中指定位置的元素,返回值的更新前的元素宗雇。
        //把最后一個(gè)a,替換為A
        String setE = list.set(4, "A");
        System.out.println("被替換的元素:"+setE);//被替換的元素:a
        System.out.println(list);//[a, b, itheima, d, A]
?
        //List集合遍歷有3種方式
        //使用普通的for循環(huán)
        for(int i=0; i<list.size(); i++){
            //public E get(int index):返回集合中指定位置的元素昂芜。
            String s = list.get(i);
            System.out.println(s);
        }
        System.out.println("-----------------");
        //使用迭代器
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("-----------------");
        //使用增強(qiáng)for
        for (String s : list) {
            System.out.println(s);
        }
?
        String r = list.get(5);//IndexOutOfBoundsException: Index 5 out-of-bounds for length 5
        System.out.println(r);
?
    }
}

②LinkedList集合

java.util.LinkedList集合 implements List接口

LinkedList集合的特點(diǎn):

1.底層是一個(gè)鏈表結(jié)構(gòu):查詢(xún)慢,增刪快
2.里邊包含了大量操作首尾元素的方法

注意:使用LinkedList集合特有的方法,不能使用多態(tài)

public void addFirst(E e):將指定元素插入此列表的開(kāi)頭。
public void addLast(E e):將指定元素添加到此列表的結(jié)尾赔蒲。
public void push(E e):將元素推入此列表所表示的堆棧泌神。
public E getFirst():返回此列表的第一個(gè)元素。
public E getLast():返回此列表的最后一個(gè)元素舞虱。
public E removeFirst():移除并返回此列表的第一個(gè)元素欢际。
public E removeLast():移除并返回此列表的最后一個(gè)元素。
public E pop():從此列表所表示的堆棧處彈出一個(gè)元素砾嫉。
public boolean isEmpty():如果列表不包含元素幼苛,則返回true。

public class LinkedList {
    public static void main(String[] args) {
        show03();
    }
?
    /*
        - public E removeFirst():移除并返回此列表的第一個(gè)元素焕刮。
        - public E removeLast():移除并返回此列表的最后一個(gè)元素舶沿。
        - public E pop():從此列表所表示的堆棧處彈出一個(gè)元素。此方法相當(dāng)于 removeFirst
     */
    private static void show03() {
        //創(chuàng)建LinkedList集合對(duì)象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
        System.out.println(linked);//[a, b, c]
?
        //String first = linked.removeFirst();
        String first = linked.pop();
        System.out.println("被移除的第一個(gè)元素:"+first);
        String last = linked.removeLast();
        System.out.println("被移除的最后一個(gè)元素:"+last);
        System.out.println(linked);//[b]
    }
?
    /*
        - public E getFirst():返回此列表的第一個(gè)元素配并。
        - public E getLast():返回此列表的最后一個(gè)元素括荡。
     */
    private static void show02() {
        //創(chuàng)建LinkedList集合對(duì)象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
?
        //linked.clear();//清空集合中的元素 在獲取集合中的元素會(huì)拋出NoSuchElementException
?
        //public boolean isEmpty():如果列表不包含元素,則返回true溉旋。
        if(!linked.isEmpty()){
            String first = linked.getFirst();
            System.out.println(first);//a
            String last = linked.getLast();
            System.out.println(last);//c
        }
    }
?
    /*
        - public void addFirst(E e):將指定元素插入此列表的開(kāi)頭畸冲。
        - public void addLast(E e):將指定元素添加到此列表的結(jié)尾。
        - public void push(E e):將元素推入此列表所表示的堆棧观腊。此方法等效于 addFirst(E)邑闲。
     */
    private static void show01() {
        //創(chuàng)建LinkedList集合對(duì)象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
        System.out.println(linked);//[a, b, c]
?
        //public void addFirst(E e):將指定元素插入此列表的開(kāi)頭。
        //linked.addFirst("www");
        linked.push("www");
        System.out.println(linked);//[www, a, b, c]
?
        //public void addLast(E e):將指定元素添加到此列表的結(jié)尾梧油。此方法等效于 add()
        linked.addLast("com");
        System.out.println(linked);//[www, a, b, c, com]
    }
}

2.Set集合

①Set集合

java.util.Set接口 extends Collection接口

Set接口的特點(diǎn):

1.不允許存儲(chǔ)重復(fù)的元素
2.沒(méi)有索引,沒(méi)有帶索引的方法,也不能使用普通的for循環(huán)遍歷

java.util.HashSet集合 implements Set接口

HashSet特點(diǎn):

1.不允許存儲(chǔ)重復(fù)的元素
2.沒(méi)有索引,沒(méi)有帶索引的方法,也不能使用普通的for循環(huán)遍歷
3.是一個(gè)無(wú)序的集合,存儲(chǔ)元素和取出元素的順序有可能不一致
4.底層是一個(gè)哈希表結(jié)構(gòu)(查詢(xún)的速度非常的快)
public class Set {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        //使用add方法往集合中添加元素
        set.add(1);
        set.add(3);
        set.add(2);
        set.add(1);
        //使用迭代器遍歷set集合
        Iterator<Integer> it = set.iterator();
        while (it.hasNext()){
            Integer n = it.next();
            System.out.println(n);//1,2,3
        }
        //使用增強(qiáng)for遍歷set集合
        System.out.println("-----------------");
        for (Integer i : set) {
            System.out.println(i);
        }
    }
}

②哈希值

哈希值:是一個(gè)十進(jìn)制的整數(shù),由系統(tǒng)隨機(jī)給出(就是對(duì)象的地址值,是一個(gè)邏輯地址,是模擬出來(lái)得到地址,不是數(shù)據(jù)實(shí)際存儲(chǔ)的物理地址)

在Object類(lèi)有一個(gè)方法,可以獲取對(duì)象的哈希值 int hashCode() 返回該對(duì)象的哈希碼值苫耸。
hashCode方法的源碼:
public native int hashCode();
native:代表該方法調(diào)用的是本地操作系統(tǒng)的方法

public class Person extends  Object{
    //重寫(xiě)hashCode方法
?
    @Override
    public int hashCode() {
        return  1;
    }
}
public class HashCode {
    public static void main(String[] args) {
        //Person類(lèi)繼承了Object類(lèi),所以可以使用Object類(lèi)的hashCode方法
        Person p1 = new Person();
        int h1 = p1.hashCode();
        System.out.println(h1);//1967205423  | 1
?
        Person p2 = new Person();
        int h2 = p2.hashCode();
        System.out.println(h2);//42121758   |  1
?
        /*
            toString方法的源碼:
                return getClass().getName() + "@" + Integer.toHexString(hashCode());
         */
        System.out.println(p1);//com.itheima.demo03.hashCode.Person@75412c2f
        System.out.println(p2);//com.itheima.demo03.hashCode.Person@282ba1e
        System.out.println(p1==p2);//false
?
        /*
            String類(lèi)的哈希值
                String類(lèi)重寫(xiě)Obejct類(lèi)的hashCode方法
         */
        String s1 = new String("abc");
        String s2 = new String("abc");
        System.out.println(s1.hashCode());//96354
        System.out.println(s2.hashCode());//96354
?
        System.out.println("重地".hashCode());//1179395
        System.out.println("通話(huà)".hashCode());//1179395
    }
}

③HashSet集合

import java.util.HashSet;
/**
 * Set集合不允許存儲(chǔ)重復(fù)元素的原理
 */
public class HashSetSaveString {
    public static void main(String[] args) {
        //創(chuàng)建HashSet集合對(duì)象
        HashSet<String> set = new HashSet<>();
        String s1 = new String("abc");
        String s2 = new String("abc");
        set.add(s1);
        set.add(s2);
        set.add("重地");
        set.add("通話(huà)");
        set.add("abc");
        System.out.println(set);//[重地, 通話(huà), abc]
    }
}
import java.util.HashSet;
/*
    HashSet存儲(chǔ)自定義類(lèi)型元素
    set集合報(bào)錯(cuò)元素唯一:
        存儲(chǔ)的元素(String,Integer,...Student,Person...),必須重寫(xiě)hashCode方法和equals方法
    要求:
        同名同年齡的人,視為同一個(gè)人,只能存儲(chǔ)一次
 */
public class HashSetSavePerson {
    public static void main(String[] args) {
        //創(chuàng)建HashSet集合存儲(chǔ)Person
        HashSet<Person> set = new HashSet<>();
        Person p1 = new Person("小姐姐",18);
        Person p2 = new Person("小姐姐",18);
        Person p3 = new Person("小姐姐",19);
        System.out.println(p1.hashCode());//1967205423
        System.out.println(p2.hashCode());//42121758
?
        System.out.println(p1==p2);//false
        System.out.println(p1.equals(p2));//false
        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);
    }
}
import java.util.Objects;
?
public class Person {
    private String name;
    private int age;
?
    public Person() {
    }
?
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
?
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }
?
    @Override
    public int hashCode() {
?
        return Objects.hash(name, age);
    }
?
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", 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;
    }
}

④LinkedHashSet集合

import java.util.HashSet;
import java.util.LinkedHashSet;
?
/*
    java.util.LinkedHashSet集合 extends HashSet集合
    LinkedHashSet集合特點(diǎn):
        底層是一個(gè)哈希表(數(shù)組+鏈表/紅黑樹(shù))+鏈表:多了一條鏈表(記錄元素的存儲(chǔ)順序),保證元素有序
 */
public class Demo04LinkedHashSet {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("www");
        set.add("abc");
        set.add("abc");
        set.add("itcast");
        System.out.println(set);//[abc, www, itcast] 無(wú)序,不允許重復(fù)
?
        LinkedHashSet<String> linked = new LinkedHashSet<>();
        linked.add("www");
        linked.add("abc");
        linked.add("abc");
        linked.add("itcast");
        System.out.println(linked);//[www, abc, itcast] 有序,不允許重復(fù)
    }
}

3.可變參數(shù)

使用前提:

當(dāng)方法的參數(shù)列表數(shù)據(jù)類(lèi)型已經(jīng)確定,但是參數(shù)的個(gè)數(shù)不確定,就可以使用可變參數(shù). 使用格式:定義方法時(shí)使用
修飾符 返回值類(lèi)型 方法名(數(shù)據(jù)類(lèi)型...變量名){} 可變參數(shù)的原理:
可變參數(shù)底層就是一個(gè)數(shù)組,根據(jù)傳遞參數(shù)個(gè)數(shù)不同,會(huì)創(chuàng)建不同長(zhǎng)度的數(shù)組,來(lái)存儲(chǔ)這些參數(shù)
傳遞的參數(shù)個(gè)數(shù),可以是0個(gè)(不傳遞),1,2...多個(gè)

public class Demo01VarArgs {
    public static void main(String[] args) {
        //int i = add();
        //int i = add(10);
        int i = add(10,20);
        //int i = add(10,20,30,40,50,60,70,80,90,100);
        System.out.println(i);
?
        method("abc",5.5,10,1,2,3,4);
    }
?
    /*
        可變參數(shù)的注意事項(xiàng)
            1.一個(gè)方法的參數(shù)列表,只能有一個(gè)可變參數(shù)
            2.如果方法的參數(shù)有多個(gè),那么可變參數(shù)必須寫(xiě)在參數(shù)列表的末尾
     */
    /*public static void method(int...a,String...b){
錯(cuò)誤寫(xiě)法
    }*/
?
    /*public static void method(String b,double c,int d,int...a){
    }*/
?
    //可變參數(shù)的特殊(終極)寫(xiě)法
    public static void method(Object...obj){
?
    }
?
    /*
        定義計(jì)算(0-n)整數(shù)和的方法
        已知:計(jì)算整數(shù)的和,數(shù)據(jù)類(lèi)型已經(jīng)確定int
        但是參數(shù)的個(gè)數(shù)不確定,不知道要計(jì)算幾個(gè)整數(shù)的和,就可以使用可變參數(shù)
        add(); 就會(huì)創(chuàng)建一個(gè)長(zhǎng)度為0的數(shù)組, new int[0]
        add(10); 就會(huì)創(chuàng)建一個(gè)長(zhǎng)度為1的數(shù)組,存儲(chǔ)傳遞來(lái)過(guò)的參數(shù) new int[]{10};
        add(10,20); 就會(huì)創(chuàng)建一個(gè)長(zhǎng)度為2的數(shù)組,存儲(chǔ)傳遞來(lái)過(guò)的參數(shù) new int[]{10,20};
        add(10,20,30,40,50,60,70,80,90,100); 就會(huì)創(chuàng)建一個(gè)長(zhǎng)度為2的數(shù)組,存儲(chǔ)傳遞來(lái)過(guò)的參數(shù) new int[]{10,20,30,40,50,60,70,80,90,100};
     */
    public static int add(int...arr){
        //System.out.println(arr);//[I@2ac1fdc4 底層是一個(gè)數(shù)組
        //System.out.println(arr.length);//0,1,2,10
        //定義一個(gè)初始化的變量,記錄累加求和
        int sum = 0;
        //遍歷數(shù)組,獲取數(shù)組中的每一個(gè)元素
        for (int i : arr) {
            //累加求和
            sum += i;
        }
        //把求和結(jié)果返回
        return sum;
    }
}

4.Map集合

①M(fèi)ap集合

java.util.Map<k,v>集合

Map集合的特點(diǎn):

1.Map集合是一個(gè)雙列集合,一個(gè)元素包含兩個(gè)值(一個(gè)key,一個(gè)value)
2.Map集合中的元素,key和value的數(shù)據(jù)類(lèi)型可以相同,也可以不同
3.Map集合中的元素,key是不允許重復(fù)的,value是可以重復(fù)的
4.Map集合中的元素,key和value是一一對(duì)應(yīng)

java.util.HashMap<k,v>集合 implements Map<k,v>接口

HashMap集合的特點(diǎn):

1.HashMap集合底層是哈希表:查詢(xún)的速度特別的快
JDK1.8之前:數(shù)組+單向鏈表
JDK1.8之后:數(shù)組+單向鏈表|紅黑樹(shù)(鏈表的長(zhǎng)度超過(guò)8):提高查詢(xún)的速度
2.hashMap集合是一個(gè)無(wú)序的集合,存儲(chǔ)元素和取出元素的順序有可能不一致 1

java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合

LinkedHashMap的特點(diǎn):

1.LinkedHashMap集合底層是哈希表+鏈表(保證迭代的順序)
2.LinkedHashMap集合是一個(gè)有序的集合,存儲(chǔ)元素和取出元素的順序是一致的

public class Map {
    public static void main(String[] args) {
        show04();
    }
    /*
        boolean containsKey(Object key) 判斷集合中是否包含指定的鍵。
        包含返回true,不包含返回false
     */
    private static void show04() {
        //創(chuàng)建Map集合對(duì)象
        Map<String,Integer> map = new HashMap<>();
        map.put("趙麗穎",168);
        map.put("楊穎",165);
        map.put("林志玲",178);
?
        boolean b1 = map.containsKey("趙麗穎");
        System.out.println("b1:"+b1);//b1:true
?
        boolean b2 = map.containsKey("趙穎");
        System.out.println("b2:"+b2);//b2:false
    }
?
    /*
        public V get(Object key) 根據(jù)指定的鍵儡陨,在Map集合中獲取對(duì)應(yīng)的值褪子。
            返回值:
                key存在,返回對(duì)應(yīng)的value值
                key不存在,返回null
     */
    private static void show03() {
        //創(chuàng)建Map集合對(duì)象
        Map<String,Integer> map = new HashMap<>();
        map.put("趙麗穎",168);
        map.put("楊穎",165);
        map.put("林志玲",178);
?
        Integer v1 = map.get("楊穎");
        System.out.println("v1:"+v1);//v1:165
?
        Integer v2 = map.get("迪麗熱巴");
        System.out.println("v2:"+v2);//v2:null
    }
?
    /*
        public V remove(Object key): 把指定的鍵 所對(duì)應(yīng)的鍵值對(duì)元素 在Map集合中刪除,返回被刪除元素的值骗村。
            返回值:V
                key存在,v返回被刪除的值
                key不存在,v返回null
     */
    private static void show02() {
        //創(chuàng)建Map集合對(duì)象
        Map<String,Integer> map = new HashMap<>();
        map.put("趙麗穎",168);
        map.put("楊穎",165);
        map.put("林志玲",178);
        System.out.println(map);//{林志玲=178, 趙麗穎=168, 楊穎=165}
?
        Integer v1 = map.remove("林志玲");
        System.out.println("v1:"+v1);//v1:178
?
        System.out.println(map);//{趙麗穎=168, 楊穎=165}
?
        //int v2 = map.remove("林志穎");//自動(dòng)拆箱  NullPointerException
        Integer v2 = map.remove("林志穎");
        System.out.println("v2:"+v2);//v2:null
?
        System.out.println(map);//{趙麗穎=168, 楊穎=165}
    }
?
    /*
        public V put(K key, V value):  把指定的鍵與指定的值添加到Map集合中嫌褪。
            返回值:v
                存儲(chǔ)鍵值對(duì)的時(shí)候,key不重復(fù),返回值V是null
                存儲(chǔ)鍵值對(duì)的時(shí)候,key重復(fù),會(huì)使用新的value替換map中重復(fù)的value,返回被替換的value值
     */
    private static void show01() {
        //創(chuàng)建Map集合對(duì)象,多態(tài)
        Map<String,String> map = new HashMap<>();
?
        String v1 = map.put("李晨", "范冰冰1");
        System.out.println("v1:"+v1);//v1:null
?
        String v2 = map.put("李晨", "范冰冰2");
        System.out.println("v2:"+v2);//v2:范冰冰1
?
        System.out.println(map);//{李晨=范冰冰2}
?
        map.put("冷鋒","龍小云");
        map.put("楊過(guò)","小龍女");
        map.put("尹志平","小龍女");
        System.out.println(map);//{楊過(guò)=小龍女, 尹志平=小龍女, 李晨=范冰冰2, 冷鋒=龍小云}
    }
}

Map集合的第一種遍歷方式:通過(guò)鍵找值的方式

Map集合中的方法:

Set<K> keySet() 返回此映射中包含的鍵的 Set 視圖。

實(shí)現(xiàn)步驟:

1.使用Map集合中的方法keySet(),把Map集合所有的key取出來(lái),存儲(chǔ)到一個(gè)Set集合中
2.遍歷set集合,獲取Map集合中的每一個(gè)key
3.通過(guò)Map集合中的方法get(key),通過(guò)key找到value

public class KeySet {
    public static void main(String[] args) {
        //創(chuàng)建Map集合對(duì)象
        Map<String,Integer> map = new HashMap<>();
        map.put("李志",168);
        map.put("李德軒",165);
        map.put("方永泰",178);
?
        //1.使用Map集合中的方法keySet(),把Map集合所有的key取出來(lái),存儲(chǔ)到一個(gè)Set集合中
        Set<String> set = map.keySet();
?
        //2.遍歷set集合,獲取Map集合中的每一個(gè)key
        //使用迭代器遍歷Set集合
        Iterator<String> it = set.iterator();
        while (it.hasNext()){
            String key = it.next();
            //3.通過(guò)Map集合中的方法get(key),通過(guò)key找到value
            Integer value = map.get(key);
            System.out.println(key+"="+value);
        }
        System.out.println("-------------------");
        //使用增強(qiáng)for遍歷Set集合
        for(String key : set){
            //3.通過(guò)Map集合中的方法get(key),通過(guò)key找到value
            Integer value = map.get(key);
            System.out.println(key+"="+value);
        }
        System.out.println("-------------------");
        //使用增強(qiáng)for遍歷Set集合
        for(String key : map.keySet()){
            //3.通過(guò)Map集合中的方法get(key),通過(guò)key找到value
            Integer value = map.get(key);
            System.out.println(key+"="+value);
        }
    }
}

Map集合遍歷的第二種方式:使用Entry對(duì)象遍歷

Map集合中的方法:

Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射關(guān)系的 Set 視圖胚股。

實(shí)現(xiàn)步驟:

1.使用Map集合中的方法entrySet(),把Map集合中多個(gè)Entry對(duì)象取出來(lái),存儲(chǔ)到一個(gè)Set集合中
2.遍歷Set集合,獲取每一個(gè)Entry對(duì)象
3.使用Entry對(duì)象中的方法getKey()和getValue()獲取鍵與值

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class EntrySet {
    public static void main(String[] args) {
        //創(chuàng)建Map集合對(duì)象
        Map<String,Integer> map = new HashMap<>();
        map.put("趙麗穎",168);
        map.put("楊穎",165);
        map.put("林志玲",178);
?
        //1.使用Map集合中的方法entrySet(),把Map集合中多個(gè)Entry對(duì)象取出來(lái),存儲(chǔ)到一個(gè)Set集合中
        Set<Map.Entry<String, Integer>> set = map.entrySet();
?
        //2.遍歷Set集合,獲取每一個(gè)Entry對(duì)象
        //使用迭代器遍歷Set集合
        Iterator<Map.Entry<String, Integer>> it = set.iterator();
        while(it.hasNext()){
            Map.Entry<String, Integer> entry = it.next();
            //3.使用Entry對(duì)象中的方法getKey()和getValue()獲取鍵與值
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+"="+value);
        }
        System.out.println("-----------------------");
        for(Map.Entry<String,Integer> entry:set){
            //3.使用Entry對(duì)象中的方法getKey()和getValue()獲取鍵與值
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+"="+value);
        }
    }
}

HashMap存儲(chǔ)自定義類(lèi)型鍵值

Map集合保證key是唯一的:

作為key的元素,必須重寫(xiě)hashCode方法和equals方法,以保證key唯一

public class HashMapSavePerson {
    public static void main(String[] args) {
        show02();
    }
?
    /*
        HashMap存儲(chǔ)自定義類(lèi)型鍵值
        key:Person類(lèi)型
            Person類(lèi)就必須重寫(xiě)hashCode方法和equals方法,以保證key唯一
        value:String類(lèi)型
            可以重復(fù)
     */
    private static void show02() {
        //創(chuàng)建HashMap集合
        HashMap<Person,String> map = new HashMap<>();
        //往集合中添加元素
        map.put(new Person("女王",18),"英國(guó)");
        map.put(new Person("秦始皇",18),"秦國(guó)");
        map.put(new Person("普京",30),"俄羅斯");
        map.put(new Person("女王",18),"毛里求斯");
        //使用entrySet和增強(qiáng)for遍歷Map集合
        Set<Map.Entry<Person, String>> set = map.entrySet();
        for (Map.Entry<Person, String> entry : set) {
            Person key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"-->"+value);
        }
    }
?
    /*
        HashMap存儲(chǔ)自定義類(lèi)型鍵值
        key:String類(lèi)型
            String類(lèi)重寫(xiě)hashCode方法和equals方法,可以保證key唯一
        value:Person類(lèi)型
            value可以重復(fù)(同名同年齡的人視為同一個(gè))
     */
    private static void show01() {
        //創(chuàng)建HashMap集合
        HashMap<String,Person> map = new HashMap<>();
        //往集合中添加元素
        map.put("北京",new Person("張三",18));
        map.put("上海",new Person("李四",19));
        map.put("廣州",new Person("王五",20));
        map.put("北京",new Person("趙六",18));
        //使用keySet加增強(qiáng)for遍歷Map集合
        Set<String> set = map.keySet();
        for (String key : set) {
            Person value = map.get(key);
            System.out.println(key+"-->"+value);
        }
    }
}
import java.util.Objects;
?
public class Person {
    private String name;
    private  int age;
?
    public Person() {
    }
?
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
?
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
?
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }
?
    @Override
    public int hashCode() {
?
        return Objects.hash(name, 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;
    }
}

②LinkedHashMap集合

java.util.LinkedHashMap<K,V> entends HashMap<K,V>

Map 接口的哈希表和鏈接列表實(shí)現(xiàn)笼痛,具有可預(yù)知的迭代順序。 底層原理:
哈希表+鏈表(記錄元素的順序)

public class LinkedHashMap {
    public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put("a","a");
        map.put("c","c");
        map.put("b","b");
        map.put("a","d");
        System.out.println(map);// key不允許重復(fù),無(wú)序 {a=d, b=b, c=c}
?
        LinkedHashMap<String,String> linked = new LinkedHashMap<>();
        linked.put("a","a");
        linked.put("c","c");
        linked.put("b","b");
        linked.put("a","d");
        System.out.println(linked);// key不允許重復(fù),有序 {a=d, c=c, b=b}
    }
}

③Hashtable集合

java.util.Hashtable<K,V>集合 implements Map<K,V>接口

Hashtable:底層也是一個(gè)哈希表,是一個(gè)線(xiàn)程安全的集合,是單線(xiàn)程集合,速度慢
HashMap:底層是一個(gè)哈希表,是一個(gè)線(xiàn)程不安全的集合,是多線(xiàn)程的集合,速度快 HashMap集合(前面所有的集合):可以存儲(chǔ)null值
Hashtable集合,不能存儲(chǔ)null值,null鍵

Hashtable和Vector集合一樣,在jdk1.2版本之后被更先進(jìn)的集合(HashMap,ArrayList)取代了
Hashtable的子類(lèi)Properties依然活躍在歷史舞臺(tái) Properties集合是一個(gè)唯一和IO流相結(jié)合的集合

public class Hashtable {
    public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put(null,"a");
?        map.put("b",null);
        map.put(null,null);
        System.out.println(map);//{null=null, b=null}
?
        Hashtable<String,String> table = new Hashtable<>();
        //table.put(null,"a");//NullPointerException
        //table.put("b",null);//NullPointerException
        table.put(null,null);//NullPointerException
    }
}

5.of方法

List接口,Set接口,Map接口:里邊增加了一個(gè)靜態(tài)的方法of,可以給集合一次性添加多個(gè)元素 static List of(E…
elements)
使用前提:
當(dāng)集合中存儲(chǔ)的元素的個(gè)數(shù)已經(jīng)確定了,不在改變時(shí)使用

注意:

1.of方法只適用于List接口,Set接口,Map接口,不適用于接接口的實(shí)現(xiàn)類(lèi)
2.of方法的返回值是一個(gè)不能改變的集合,集合不能再使用add,put方法添加元素,會(huì)拋出異常
3.Set接口和Map接口在調(diào)用of方法的時(shí)候,不能有重復(fù)的元素,否則會(huì)拋出異常

public class Demo {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "a", "c", "d");
        System.out.println(list);//[a, b, a, c, d]
        //list.add("w");//UnsupportedOperationException:不支持操作異常
?
        //Set<String> set = Set.of("a", "b", "a", "c", "d");//IllegalArgumentException:非法參數(shù)異常,有重復(fù)的元素
        Set<String> set = Set.of("a", "b", "c", "d");
        System.out.println(set);
        //set.add("w");//UnsupportedOperationException:不支持操作異常
?
        //Map<String, Integer> map = Map.of("張三", 18, "李四", 19, "王五", 20,"張三",19);////IllegalArgumentException:非法參數(shù)異常,有重復(fù)的元素
        Map<String, Integer> map = Map.of("張三", 18, "李四", 19, "王五", 20);
        System.out.println(map);//{王五=20, 李四=19, 張三=18}
        //map.put("趙四",30);//UnsupportedOperationException:不支持操作異常
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末琅拌,一起剝皮案震驚了整個(gè)濱河市缨伊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌财忽,老刑警劉巖倘核,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異即彪,居然都是意外死亡紧唱,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)隶校,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)漏益,“玉大人,你說(shuō)我怎么就攤上這事深胳〈掳蹋” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵舞终,是天一觀(guān)的道長(zhǎng)轻庆。 經(jīng)常有香客問(wèn)我癣猾,道長(zhǎng),這世上最難降的妖魔是什么余爆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任纷宇,我火速辦了婚禮,結(jié)果婚禮上蛾方,老公的妹妹穿的比我還像新娘像捶。我一直安慰自己,他們只是感情好桩砰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布拓春。 她就那樣靜靜地躺著,像睡著了一般亚隅。 火紅的嫁衣襯著肌膚如雪硼莽。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天枢步,我揣著相機(jī)與錄音沉删,去河邊找鬼。 笑死醉途,一個(gè)胖子當(dāng)著我的面吹牛矾瑰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播隘擎,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼殴穴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了货葬?” 一聲冷哼從身側(cè)響起采幌,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎震桶,沒(méi)想到半個(gè)月后休傍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹲姐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年磨取,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柴墩。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡忙厌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出江咳,到底是詐尸還是另有隱情逢净,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站爹土,受9級(jí)特大地震影響甥雕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜着饥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一犀农、第九天 我趴在偏房一處隱蔽的房頂上張望惰赋。 院中可真熱鬧宰掉,春花似錦、人聲如沸赁濒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拒炎。三九已至挪拟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間击你,已是汗流浹背玉组。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丁侄,地道東北人惯雳。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鸿摇,于是被迫代替她去往敵國(guó)和親石景。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355