1. 程式人生 > >集合框架、單列集合體系、Collection、Iterator迭代器、泛型、上限&下限【學習筆記】

集合框架、單列集合體系、Collection、Iterator迭代器、泛型、上限&下限【學習筆記】

一、單列集合
1.單列集合體系
Collection
List Set
ArrayList LinkedList HashSet LinkedHashSet

List :存取有序、有索引、還可以儲存重複的元素
    ArrayList:底層是陣列實現的,有索引,查詢快、增刪慢
    LinkedList:底層是連結串列實現的,有索引,查詢慢、增刪快
Set : 存取無序、沒有索引、不可以儲存重複的元素
    HashSet:底層是雜湊表+紅黑樹的,存取無序、沒有索引、不可以儲存重複的元素
    LinkedHashSet:底層是連結串列+雜湊表實現的,可以保證存取順序,沒有索引、不可以儲存重複的元素

2.Collection介面中的共性的功能
        boolean add(E e);           向集合中新增元素
        void clear();               清空集合所有的元素
        boolean remove(E e);        刪除指定的元素
        boolean contains(E e);      判斷集合中是否包含傳入的元素
        boolean isEmpty();          判斷集合是否為空
        int size();                 獲取集合的長度
        Object[] toArray();         將集合轉成陣列

        示例程式碼:
            public
class Demo01Collection { public static void main(String[] args) { //建立集合物件,可以使用多型 //Collection<String> coll = new ArrayList<>(); Collection<String> coll = new HashSet<>(); System.out.println(coll);//重寫了toString方法 []
/* public boolean add(E e): 把給定的物件新增到當前集合中 。 返回值是一個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): 把給定的物件在當前集合中刪除。 返回值是一個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): 判斷當前集合中是否包含給定的物件。 包含返回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(): 判斷當前集合是否為空。 集合為空返回true,集合不為空返回false boolean b6 = coll.isEmpty(); System.out.println("b6:"+b6);//b6:false //public int size(): 返回集合中元素的個數。 int size = coll.size(); System.out.println("size:"+size);//size:3 //public Object[] toArray(): 把集合中的元素,儲存到陣列中。 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 } }

二、迭代器
1.Iterator介面
作用:通用的對於集合的遍歷形式
獲取迭代器物件的方式:Iterator<> it = 集合物件.iterator();
2.常用方法:
boolean hashNext(); 判斷迭代器中是否有元素
E next(); 獲取元素
void remove(); 刪除元素
3.示例程式碼

        public class Demo01Iterator {
            public static void main(String[] args) {
                //建立一個集合物件
                Collection<String> coll = new ArrayList<>();
                //往集合中新增元素
                coll.add("姚明");
                coll.add("科比");
                coll.add("麥迪");
                coll.add("詹姆斯");
                coll.add("艾弗森");

                /*
                    1.使用集合中的方法iterator()獲取迭代器的實現類物件,使用Iterator介面接收(多型)
                    注意:
                        Iterator<E>介面也是有泛型的,迭代器的泛型跟著集合走,集合是什麼泛型,迭代器就是什麼泛型
                 */
                //多型  介面            實現類物件
                Iterator<String> it = coll.iterator();
                /*
                    發現使用迭代器取出集合中元素的程式碼,是一個重複的過程
                    所以我們可以使用迴圈優化
                    不知道集合中有多少元素,使用while迴圈
                    迴圈結束的條件,hasNext方法返回false
                 */
                while(it.hasNext()){
                    String e = it.next();
                    System.out.println(e);
                }
            }
        }
4.使用迭代器對集合元素進行操作
        /*
            迭代器的使用注意事項:
                next()方法每呼叫一次都會將指標向後移動一位

               在使用迭代器進行遍歷的時候,如果向集合中新增元素。那麼會出現併發修改異常
               解決方式:
                使用List集合特有的迭代器物件:ListIterator
         */
        public class Demo01 {
            public static void main(String[] args) {
                ArrayList<String> list = new ArrayList<>();
                list.add("蒼老師");
                list.add("小澤老師");
                list.add("波多老師");
                list.add("風間老師");

                //使用迭代器遍歷集合
                //Iterator<String> it = list.iterator();
                ListIterator<String> it = list.listIterator();

                while(it.hasNext()) {
                    String name = it.next();
                    if(name.equals("波多老師")) {
                        //it.remove();  可以刪除成功
                        //list.remove(name); 可以刪除成功
                        //list.add("東尼老師");   // 併發修改異常 ConcurrentModificationException
                        it.add("東尼老師");
                    }
                }

                System.out.println(list);
            }
        }

三、增強for迴圈
1.定義格式
for(容器的資料型別 變數名 : 容器物件) {
迴圈體;
}
2.示例程式碼

四、泛型
1.自己定義一個泛型類

//帶有泛型的類
public class GenericClass<E> {
private E name;

public E getName() {
return name;
}

public void setName(E name) {
this.name = name;
}
}

//測試類
public class Demo02GenericClass {
public static void main(String[] args) {
//不寫泛型預設為Object型別
GenericClass gc = new GenericClass();
gc.setName("只能是字串");
Object obj = gc.getName();

//建立GenericClass物件,泛型使用Integer型別
GenericClass<Integer> gc2 = new GenericClass<>();
gc2.setName(1);

Integer name = gc2.getName();
System.out.println(name);

//建立GenericClass物件,泛型使用String型別
GenericClass<String> gc3 = new GenericClass<>();
gc3.setName("小明");
String name1 = gc3.getName();
System.out.println(name1);
}
}
2.自己定義一個泛型方法
        //帶有泛型方法的類
        public class GenericMethod {
            //定義一個含有泛型的方法
            public <M> void method01(M m){
                System.out.println(m);
            }

            //定義一個含有泛型的靜態方法
            public static <S> void method02(S s){
                System.out.println(s);
            }
        }

        //測試類
        public class Demo03GenericMethod {
            public static void main(String[] args) {
                //建立GenericMethod物件
                GenericMethod gm = new GenericMethod();

                /*
                    呼叫含有泛型的方法method01
                    傳遞什麼型別,泛型就是什麼型別
                 */
                gm.method01(10);
                gm.method01("abc");
                gm.method01(8.8);
                gm.method01(true);

                gm.method02("靜態方法,不建議建立物件使用");

                //靜態方法,通過類名.方法名(引數)可以直接使用
                GenericMethod.method02("靜態方法");
                GenericMethod.method02(1);
            }
        }
3.自定義一個帶有泛型的介面
        //帶有泛型的介面
        public interface GenericInterface<I> {
            public abstract void method(I i);
        }

        //第一種實現類的方式
        public class GenericInterfaceImpl1 implements GenericInterface<String>{
            @Override
            public void method(String s) {
                System.out.println(s);
            }
        }

        //第二種實現類的方式
        public class GenericInterfaceImpl2<I> implements GenericInterface<I> {
            @Override
            public void method(I i) {
                System.out.println(i);
            }
        }

        //測試類
        public class Demo04GenericInterface {
            public static void main(String[] args) {
                //建立GenericInterfaceImpl1物件
                GenericInterfaceImpl1 gi1 = new GenericInterfaceImpl1();
                gi1.method("字串");


                //建立GenericInterfaceImpl2物件
                GenericInterfaceImpl2<Integer> gi2 = new GenericInterfaceImpl2<>();
                gi2.method(10);

                GenericInterfaceImpl2<Double> gi3 = new GenericInterfaceImpl2<>();
                gi3.method(8.8);
            }
        }
4.泛型的萬用字元
    萬用字元:?
            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<?>();
                }

                /*
                    定義一個方法,能遍歷所有型別的ArrayList集合
                    這時候我們不知道ArrayList集合使用什麼資料型別,可以泛型的萬用字元?來接收資料型別
                    注意:
                        泛型沒有繼承概念的
                 */
                public static void printArray(ArrayList<?> list){
                    //使用迭代器遍歷集合
                    Iterator<?> it = list.iterator();
                    while(it.hasNext()){
                        //it.next()方法,取出的元素是Object,可以接收任意的資料型別
                        Object o = it.next();
                        System.out.println(o);
                    }
                }
            }
    上下限定:
        ? extends E  只能傳遞的是E這個型別本身或者是E型別的子類
        ? super E    只能傳遞的是E這個型別本身或者是E型別的父類
    示例程式碼:
            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);//報錯
                    getElement1(list3);
                    //getElement1(list4);//報錯

                    //getElement2(list1);//報錯
                    //getElement2(list2);//報錯
                    getElement2(list3);
                    getElement2(list4);

                    /*
                        類與類之間的繼承關係
                        Integer extends Number extends Object
                        String extends Object
                     */

                }
                // 泛型的上限:此時的泛型?,必須是Number型別或者Number型別的子類
                public static void getElement1(Collection<? extends Number> coll){}
                // 泛型的下限:此時的泛型?,必須是Number型別或者Number型別的父類
                public static void getElement2(Collection<? super Number> coll){}
            }

五、案例
1.將偶數放在集合的左邊,將奇數放在集合的右邊

        /*
            定義一個集合,儲存1-10的數字
            將集合中偶數元素放到左邊,奇數元素放到右邊。(不能建立其他集合)
            例如:
                [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
                [2, 4, 6, 8, 10, 3, 7, 1, 9, 5]
         */
        public class Test01 {
            public static void main(String[] args) {
                ArrayList<Integer> list = new ArrayList<>();
                for (int i = 1; i <= 10; i++) {
                    list.add(i);
                }

                System.out.println(list);


                int index = 0;

                //遍歷集合,拿到每一個數字
                for (int i = 0; i < list.size(); i++) {
                    int num1 = list.get(i);
                    int num2 = list.get(index);
                    if(num1 % 2 == 0) {
                        list.set(i,num2);
                        list.set(index,num1);
                        index++;
                    }
                }

                System.out.println(list);
            }
        }
2.隨機雙色球生成器
        public class Test02 {
            public static void main(String[] args) {
                //儲存購買的號碼
                ArrayList<String> list = new ArrayList<>();

                list.add("8 12 23 25 26 31 8");
                list.add("6 11 24 27 30 32 10");
                list.add("4 7 12 16 19 22 12");
                list.add("9 13 16 25 27 29 4");

                while(true) {
                    ArrayList<Integer> red = new ArrayList<>();
                    Random r = new Random();
                    while(red.size() != 6) {
                        int num = r.nextInt(33)+1;
                        if(!red.contains(num)) {
                            red.add(num);
                        }
                    }

                    Collections.sort(red);

                    int blue = r.nextInt(16)+1;

                    String s = "";
                    for(int i : red) {
                        s += i;
                        s += " ";
                    }
                    s += blue;

                    if(!list.contains(s)) {
                        System.out.println(s);
                        break;
                    }
                }
            }
        }