天天看點

ArrayList、Vector、LinkedList、泛型機制、可變參數、增強for循環

ArrayList、Vector、LinkedList、泛型機制、可變參數、增強for循環

ArrayList集合

1.ArrayList集合:
   List 接口的大小可變數組的實作。實作了所有可選清單操作,并允許包括 null 在内的所有元素
   ArrayList:底層使用使用的是數組。查詢快,增删慢  注意,此實作不是同步的 線程不安全 。 效率高
   元素有序的(存取順序一緻),元素編有索引 允許元素重複
2.ArrayList集合特有的周遊方式:
   void forEach(Consumer<? super E> action) 執行特定動作的每一個元素的 Iterable直到所有元素都被處理或操作抛出異常 
案例:
public class MyTest1 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(100);
        list.add(100);
        list.add(100);
        list.add(200);
        list.add(300);
        list.add(400);
        list.add(null);//允許置空

        //周遊方式:兩種疊代器
        Iterator iterator = list.iterator();
        ListIterator listIterator = list.listIterator();
        //for循環
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        System.out.println("==============================");
        //JDK1.8 提供的一種疊代方法
        //void forEach(Consumer<? super E> action)
        //執行特定動作的每一個元素的 Iterable直到所有元素都被處理或操作抛出異常
        list.forEach(new Consumer() {
            @Override
            public void accept(Object o) {
                //o就是集合中的元素
                System.out.println(o);
            }
        });
    }
}
3.ArrayList集合中的排序功能:sort()方法
案例:
public class MyTest3 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(100);
        list.add(20);
        list.add(40);
        list.add(200);
        list.add(300);
        list.add(400);
     /*   void sort (Comparator < ? super E > c)
        分類清單使用提供的 Comparator比較元素。*/

        //排序 使用的是Comparator比較器
        list.sort(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Integer aa= (Integer) o1;
                Integer bb= (Integer) o2;
                return aa-bb;
            }
        });
        System.out.println(list);
    }
}
4.ArrayList集合中的删除特定元素的功能:removeIf()方法
案例:
public class MyTest4 {
    public static void main(String[] args) {
        /*  boolean removeIf (Predicate < ? super E > filter)
        删除滿足給定謂詞的這個集合的所有元素。*/
        ArrayList list = new ArrayList();
        list.add(100);
        list.add(20);
        list.add(40);
        list.add(200);
        list.add(300);
        list.add(400);
        //删除集合中大于100的元素
        //删除集合中符合條件的元素

        list.removeIf(new Predicate() {
            @Override
            public boolean test(Object o) {
                Integer num= (Integer) o;
                return num>100;//num>100為true就表示num大于100  此時就删除集合中的元素  否則就不删
            }
        });
        System.out.println(list);
    }
}

           

Vector集合

1.Vector集合:
 Vector類概述:	Vector 類可以實作可增長的對象數組 , Vector 是同步的。 
2.Vector集合的特有功能:
 	public void addElement(E obj)
 	向Vector集合中添加元素
	public E elementAt(int index)
	向Vector集合中的指定索引處添加元素
	public Enumeration elements()
	Vector集合中特有的疊代器
    E firstElement ()
    傳回此向量的第一個元件(位于索引 0)處的項)。
    E lastElement ()
    傳回此向量的最後一個元件。
案例:
public class MyTest1 {
    public static void main(String[] args) {
        Vector vector = new Vector();
        vector.add("aaaa");
        vector.addElement("bbb");
        vector.forEach(new Consumer() {
            @Override
            public void accept(Object o) {

                System.out.println(o);
            }
        });

        System.out.println("===================");
        Object o = vector.lastElement();
        System.out.println(o);
        //根據索引截取一個元素
        Object o1 = vector.elementAt(0);
        System.out.println(o1);
    }
}
案例2:
public class MyTest2 {
    public static void main(String[] args) {
        //Vector集合中也有自己的疊代器
            /*   Enumeration<E> elements ()
        傳回此向量的元件的枚舉。*/
        Vector vector = new Vector();
        vector.addElement(100);
        vector.addElement(200);
        vector.addElement(300);
        vector.addElement(400);
        vector.addElement(500);
        //Enumeration 疊代器
        // hasMoreElements()  判斷還有沒有下個元素
        // nextElement() 擷取下一個元素
        Enumeration elements = vector.elements();
        while (elements.hasMoreElements()) {
            Object o = elements.nextElement();
            System.out.println(o);
        }
    }
}

           

LinkedList集合

1,LinkedList集合:
   底層資料結構是連結清單,查詢慢,增删快,注意,此實作不是同步的。線程不安全,效率高
2。LinkedList類特有功能
	public void addFirst(E e)及addLast(E e)
	向LinkedList集合中開始位置和結束位置添加元素
	public E getFirst()及getLast()
	擷取LinkedList集合中初始位置和結束位置的元素
	public E removeFirst()及public E removeLast()
	删除并傳回LinkedList集合中開始位置和結束位置的元素
    E poll ()
    擷取并移除此清單的頭(第一個元素)
    E pollFirst ()
	擷取并移除此清單的第一個元素;如果此清單為空,則傳回 null。
	E pollLast ()
	擷取并移除此清單的最後一個元素;如果此清單為空,則傳回 null。
    E pop ()
	從此清單所表示的堆棧處彈出一個元素。
    void push (E e)
	将元素推入此清單所表示的堆棧。


案例:
public class MyTest1 {
    public static void main(String[] args) {
        //LinkedList:底層資料結構是連結清單,查詢慢,增删快,注意,此實作不是同步的。線程不安全,效率高
        LinkedList linkedList = new LinkedList();
        linkedList.addLast(100);
        linkedList.addLast(200);
        linkedList.addLast(300);
        linkedList.addLast(400);
        //System.out.println(linkedList);
        System.out.println("===================");
        Object last = linkedList.getLast();
        Object first = linkedList.getFirst();
        linkedList.get(0);
        Object remove = linkedList.remove(0);
    }
}
案例2:
public class MyTest2 {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.addLast(100);
        linkedList.addLast(200);
        linkedList.addLast(300);
        linkedList.addLast(400);

        Object poll = linkedList.poll();
        System.out.println(poll);
        System.out.println(linkedList);
        System.out.println("===========================");
        poll = linkedList.poll();
        System.out.println(poll);
        System.out.println(linkedList);
        System.out.println("===========================");
        poll = linkedList.poll();
        System.out.println(poll);
        System.out.println(linkedList);
        System.out.println("===========================");
        poll = linkedList.poll();
        System.out.println(poll);
        System.out.println(linkedList);
        System.out.println("===========================");
        poll = linkedList.poll();
        System.out.println(poll);
        System.out.println(linkedList);
        System.out.println("===========================");
    }
}
案例3:
public class MyTest3 {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add(100);
        linkedList.add(200);
        linkedList.add(300);
        linkedList.add(400);
        linkedList.push(600);
        linkedList.push(800);
        System.out.println(linkedList);

        Object pop = linkedList.pop();
        System.out.println(linkedList);
        System.out.println("========================");
        pop = linkedList.pop();
        System.out.println(linkedList);
        System.out.println("========================");
        pop = linkedList.pop();
        System.out.println(linkedList);
        System.out.println("========================");
    }
}

           

案例:需求:請用LinkedList模拟棧資料結構的集合,并測試

案例:
棧的資料結構:先進後出,後進先出
public class MyList {
    private final LinkedList linkedList;

    public MyList() {
        linkedList = new LinkedList();
    }

    //1.添加元素的方法
    public void addEle(Object obj){
        //調用LinkedList裡面的方法 來添加元素
        //500 400 300 200 100
        linkedList.addFirst(obj);
    }

    //2.取出元素的方法
    public Object getEle(){
        Object pop = linkedList.pop();
        //再将它添加回去
        linkedList.addLast(pop);
        return pop;
    }
}
package org.westos.demo8;

public class MyTest2 {
    public static void main(String[] args) {

        MyList myList = new MyList();
        myList.addEle(100);
        myList.addEle(200);
        myList.addEle(300);
        myList.addEle(400);
        myList.addEle(500);

        Object ele = myList.getEle();
        System.out.println(ele);
        ele = myList.getEle();
        System.out.println(ele);
        ele = myList.getEle();
        System.out.println(ele);
        ele = myList.getEle();
        System.out.println(ele);
        ele = myList.getEle();
        System.out.println(ele);

    }
}

           

案例:需求:ArrayList去除集合中字元串的重複值(字元串的内容相同)

1.方式1:建立新集合的方法
 
public class MyTest {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");
        System.out.println(list);
        //思路:建立新集合方式
        ArrayList newList = new ArrayList();
        //周遊舊集合
        for (int i = 0; i < list.size(); i++) {
            Object obj = list.get(i);
            //取出舊集合中的元素往新集合中裝,判斷集合中是否包含這個元素,再往裡面添加元素
            if(!newList.contains(obj)){
                newList.add(obj);
            }
        }
        System.out.println(newList);
    }
}
2.方式2:不建立新集合,隻在原來的集合中操作
 分析:可以使用選擇排序的算法原理,每次用一個元素和後面的元素比較,如果相等就删除掉
public class MyTest {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(200); //0
        list.add(200); //1
        list.add(200); //2
        list.add(2);
        list.add(20);
        list.add(20);
        list.add(300);
        list.add(350);
        list.add(200);
        list.add(2);
        list.add(20);
        list.add(20);
        list.add(300);
        list.add(350);
        list.add(200);
        list.add(2);
        list.add(20);
        list.add(20);
        list.add(300);
        list.add(350);
        list.add(350);
        list.add(200);
        list.add(2);
        list.add(20);
        list.add(20);
        list.add(300);
        list.add(350);
        //去除集合中的重複元素,要求,不能重建新的容器來做,就在本容器中操作
        for (int i = 0; i < list.size() - 1; i++) {
            for (int i1 = i+1; i1 < list.size(); i1++) {
                //如果遇到相同的元素,就删掉
                if(list.get(i).equals(list.get(i1))){
                    list.remove(i1);
                    i1--;
                }
            }
        }
        System.out.println(list);
    }
}

           

泛型機制

1. 泛型機制:是一種将資料類型明确工作,推遲到建立對象或調用方法時才去明确的一種機制。
   泛型的好處,可以避免向下轉型,也可以提高程式的擴充性。
   泛型的文法 <類型>  <類型,類型2,。。。。> 類型指的是引用類型
   泛型可以定義在類上 接口上 方法上
   泛型隻在編譯期有效,在運作期就擦除了.
   泛型好處
	(1): 把運作時期的問題提前到了編譯期間
	(2): 避免了強制類型轉換
	(3):優化了程式設計,解決了黃色警告線
2.案例:ArrayList存儲字元串并周遊泛型版
package org.westos.demo1;

import java.util.ArrayList;

public class MyTest1 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("abc");
        //list1.add(200);報錯
        String s = list1.get(0);//避免了向下轉型

        ArrayList<Integer> list2 = new ArrayList<>();
        //list2.add("abg");報錯
        list2.add(200);
        Integer integer = list2.get(0);
        System.out.println(integer);

        System.out.println("==================================");
        //集合中可以存儲多種多樣的引用類型 你把泛型明确成Object

        ArrayList<Object> list3 = new ArrayList();
        list3.add(new Integer(200));
        list3.add(new Integer(300));
        list3.add(new Integer(400));
        list3.add("abc");
        list3.add(3.14);
        list.add(new Object());

        Object o = list.get(2);

        //一般來說,不會在集合中存儲多種引用資料類型 ,除非你有特殊需求
    }

}
案例:	ArrayList存儲自定義對象并周遊泛型版
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        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 String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
public class MyTest2 {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student("張三",23));
        list.add(new Student("李四",24));
        //避免向下轉型
        Student student=list.get(0);

    }
}

3.泛型類的概述:把泛型定義在類上
  定義格式:		public class 類名<泛型類型1,…>
  注意事項:		泛型類型必須是引用類型
  案例示範:		泛型類的使用
- 泛型的應用之泛型類: 就是把泛型定義在類上
- 格式:		public class 類名<資料類型 , ....> {}
案例:
//設計一個類,使用上泛型,可以提高擴充性,也可以避免向下轉型
//泛型可以定義在類上
public class MyClass<T> {
    T obj;

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }
}
public class MyTest {
    public static void main(String[] args) {
        //泛型機制:是一種将資料類型明确工作,推遲到建立對象才去明确的一種機制。
        //在建立對象時才明确具體的類型
        MyClass<String> aClass = new MyClass<>();
        aClass.setObj("abc");
        String obj = aClass.getObj();
        System.out.println(obj);

        System.out.println("========================");
        MyClass<Integer> aClass1 = new MyClass<>();
        aClass1.setObj(100);
        Integer obj1 = aClass1.getObj();
        System.out.println(obj1);
    }
}

注:子類可以繼承一個泛型接口,同時,該子類可以明确具體的類型,也可以繼續使用泛型
案例:
public interface MyInterface<R,P> {
    public abstract R test(P p);
    public abstract String show(Integer num);

}
(1)明确具體類型
public class MySon implements MyInterface<Integer,String> {
    @Override
    public Integer test(String s) {
        return null;
    }

    @Override
    public String show(Integer num) {
        return null;
    }
}
(2)不明确具體類型
//子類在實作接口時,可以不急于去明确接口上的泛型,仍然定義成泛型類
public class MySon3<R,P> implements MyInterface<R,P> {
    @Override
    public R test(P p) {
        return null;
    }

    @Override
    public String show(Integer num) {
        return null;
    }
}

4.泛型方法:
 A:泛型方法概述:	把泛型定義在方法上
B:定義格式:		public <泛型類型> 傳回類型 方法名(泛型類型)
案例:
public class AA {
    //泛型方法:泛型加在方法上
    public<T> void show(T s){
        System.out.println(s);
    }
}
public class MyTest {
    public static void main(String[] args) {
        AA aa = new AA();
        //調用泛型方法時,去明确方法上的泛型,是哪種具體類型
        aa.show(3.14);
        aa.show("abc");
        aa.show(200);
    }
}

5.泛型通配符:
A:泛型通配符<?>:		任意類型,如果沒有明确,那麼就是Object以及任意的Java類了
B:? extends E:			向下限定,E及其子類
C:? super E:			向上限定,E及其父類
案例:
public class MyTest {
    public static void main(String[] args) {
        // ? 泛型通配符
        ArrayList<?> list = new ArrayList<Animal>();
        ArrayList<?> list2 = new ArrayList<Dog>();
        ArrayList<?> list3 = new ArrayList<Cat>();
        System.out.println("==============================");

        //向下限定 <? extends Animal> 是Animal本身 或者說他的子類
        ArrayList<? extends Animal> list4 = new ArrayList<Animal>();
        ArrayList<? extends Animal> list5 = new ArrayList<Dog>();
        ArrayList<? extends Animal> list6 = new ArrayList<Cat>();
        //報錯
        //ArrayList<? extends Animal> list57= new ArrayList<Object>();
        System.out.println("=======================================");
        //向上限定 <? super Animal> 是Animal本身 或者說的他的父類
        ArrayList<? super Animal> list47= new ArrayList<Animal>();
        ArrayList<? super Animal> list48 = new ArrayList<Object>();
        //ArrayList<? super Animal> list49= new ArrayList<Dog>(); //報錯
        //ArrayList<? super Animal> list491 = new ArrayList<Cat>(); //報錯
    }
}
class Animal{

}
class Dog extends Animal{

}

class Cat extends Animal{

}
           

增強for循環

1.A:增強for概述
	簡化數組和Collection集合的周遊
B:格式:
	for(元素資料類型 變量 : 數組或者Collection集合) {
		使用變量即可,該變量就是元素
	}
注意增強for循環,在疊代集合的途中,不能增删元素,會報并發修改異常
案例:
public class MyTest1 {
    public static void main(String[] args) {
        int[] arr={10,20,30};
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("=======================");
        //新式for循環來周遊數組
        //for(容中的元素資料類型 目前周遊元素的變量名:容器名
        for (int num : arr) {
            System.out.println(num);
        }
        System.out.println("=========================");
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student("張三", 23));
        list.add(new Student("李四", 24));
        for (Student student : list) {
            System.out.println(student);
        }
        System.out.println("========================");
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("Abc");
        list1.add("Abc");
        list1.add("Abc");
        list1.add("Abc");
    }
}
案例2:
public class MyTest2 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("BAbc");
        list1.add("Abc");
        list1.add("Abc");
        list1.add("Abc");
        list1.add("Abc");
        //新式for循環其實底層用的是疊代器周遊的。
      /*  for (String s : list1) {
            System.out.println(s);
        }*/
        //ConcurrentModificationException
     /* for (String s : list1) {
            if(s.startsWith("B")){
                list1.remove(s);
            }
           // System.out.println(s);
        }*/

        //我們一般用新式for循環,你隻是為了周遊看,而不是在周遊途中去增删容器中的元素,因為你增删元素,就會報并發修改異常。

        //如果你要在周遊途中增删集合中 的元素,你就使用普通for循環
        for (int i = 0; i < list1.size(); i++) {
            String s = list1.get(i);
            if (s.startsWith("B")) {
                list1.remove(s);
            }
        }

        System.out.println(list1);
    }
}

           

可變參數

1.A:可變參數概述:	定義方法的時候不知道該定義多少個參數
B:格式:			修飾符 傳回值類型 方法名(資料類型…  變量名){}
C:注意事項:
	a:	這裡的變量其實是一個數組
	b:	如果一個方法有可變參數,并且有多個參數,那麼,可變參數肯定是最後一個
案例:
public class MyTest1 {
    public static void main(String[] args) {
        int num = add1(1, 2);
        int num2 = add1(1, 2, 3);
        System.out.println(num);
        System.out.println(num2);
    }
    // 可變參數 參數資料類型 ... 參數名  一次可以接受多個實參
    // 可變參數其實是個數組,把你傳過來的多個參數放到數組中

    private static int add1(int ... i){
        //System.out.println("方法調用了");
        //System.out.println(i.length);其實是個數組 把傳過來的參數放在數組中
        int sum=0;
        for (int i1 : i) {
            sum+=i1;
        }
        return sum;
    }

    //如果一個方法,定義了多個形參,可變參數一定是最後一個。
    //文法報錯,沖突
/*    private static int add2(double... i,double num) {


       return 0;
    }*/
    //如果一個方法,定義了多個形參,可變參數一定是最後一個。
    private static int add3(String num, double... i) {
        return 0;
    }
}

           

Arrays工具類的asList()方法的使用

1.A:案例示範:Arrays工具類的asList(T... t)方法的使用:		将數組轉換成集合
案例:
public class MyTest2 {
    public static void main(String[] args) {
         /* static <T> List < T >
                asList(T...a)
        傳回一個受指定數組支援的固定大小的清單。*/
        
        //把多個值,轉換成一個集合
        List<Integer> integers = Arrays.asList(12, 20, 30);

        //把數組轉換成一個集合
        Integer[] integers1 = {200, 300, 400};
        List<Integer> integers2 = Arrays.asList(integers1);

        //把集合轉換成一個數組
        Object[] objects = integers.toArray();
    }
}