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();
}
}