day07_面向對象(Collection、泛型)
一.集合
1.集合的介紹&集合和數組的區別
什麼是集合:是一種Java中的容器
集合和數組的區別:
a.數組的長度固定 而集合的長度是可變的
b.數組可以保存任意類型 而集合只能保存引用類型
2.集合框架的介紹********
Collection 集合的根接口
-List 子接口(所有的實現類有索引)
-ArrayList 實現類
-LinkedList 實現類
-Vector 實現類(基本上不用了,底層實現和ArrayList差不多,但是性能較低)
-Set 子接口(所有的實現類無索引)
-HashSet 實現類
-LinkedHashSet 實現類
-TreeSet 實現類
3.Collection(無下標)中的通用方法******************
增:boolean add(E e)
刪:boolean remove(Object obj)
改:無(無索引)
查:無(無索引)
其他:
int size():獲取集合的長度
boolean isEmpty():判斷集合中是否有元素
boolean contains(E e):判斷集合中是否包含這個元素e
Object[] toArray():集合轉數組
void clear():清空集合
二.集合的通用遍歷方式——迭代器
1.集合迭代器的介紹和使用
什麼是迭代器:
幫助我們從集合中取出元素對象
迭代器屬於Iterator類型
public class TestIteratorDemo {
public static void main(String[] args) {
//1.創建ArrayList
Collection<String> cc = new ArrayList<String>();
cc.add("java");
cc.add("iso");
cc.add("python");
cc.add("php");
cc.add("c++");
cc.add("go");
//2.使用迭代器 遍歷集合
//a.獲取迭代器對象
Iterator<String> it = cc.iterator();
//b.先問
while (it.hasNext()) {
//c.後取
String next = it.next();
System.out.println(next);
}
}
}
迭代器的兩個注意事項(兩個異常):
a.NoSuchElementException 沒有此元素異常
b.concurrentModificationException 併發修改異常
Java規定使用迭代器的過程中不能對集合進行增刪操作,否則就拋出併發修改異常
注意:
迭代器的作用就是單純的遍歷!!!
2.迭代器的原理(畫圖)
底層原理:通過指針實現
hasNext()方法不會移動指針
next()方法會移動指針,並且取出指針移動經過的元素
3.增強for循環**********(foreach)
增強for循環是一種語法糖,底層就是迭代器(代碼格式是底層實現,看不到源碼)
格式:
for(數據類型 變量名:集合/數組){
拿到變量名
}
public class ForEachDemo {
public static void main(String[] args) {
//1.數組
int[] arr = {1,2,3,4,5,7,8,9,10};
for (int num : arr){
System.out.println(num);
}
//2.集合
ArrayList<String> names = new ArrayList<String>();
names.add("jack1");
names.add("jack2");
names.add("jack3");
names.add("jack4");
names.add("jack5");
for (String name : names) {
System.out.println(name);
}
}
}
注意:foreach循環底層就是迭代器,所以也不能在遍歷的過程中增刪元素,foreach一般用於單純的遍歷
三.泛型
1.什麼是泛型
是一種不確定的類型,由程序員在具體使用才能確定
格式:
<E>,<P>,<MVP>,...
2.泛型的好處
ArrayList arr = new ArrayList(); // 不使用泛型默認是Object
添加:
arr.add("java");
arr.add(123);
arr.add(3.14);
arr.add('A');
取出:
String s = (String)arr.get(0); // 需要強轉
String s = (String)arr.get(1); // 出現ClassCastException
泛型的好處:
a.避免了強制轉換的麻煩
b.避免了類型轉換異常,轉移到了編譯時期,變成編譯失敗
總結:
JDK1.5之後提供了泛型,Java強烈要求必須使用泛型!!!
Java的泛型是僞泛型,有種技術叫泛型的擦除,即在編譯階段會被替換 3.泛型的定義和使用
i.泛型類:類上加泛型
//泛型類定義
public class Dog<E> {
private E e;
public E getE() {
return e;
}
public void setE(E e) {
this.e = e;
}
}
//泛型類的使用
public class TestDog {
public static void main(String[] args) {
//1.使用泛型類
Dog<String> d1 = new Dog<String>();
d1.setE("aaa");
System.out.println(d1.getE());
Dog<Integer> d2 = new Dog<Integer>();
d2.setE(111);
System.out.println(d2.getE());
}
}
ii.泛型方法:在方法上加泛型
//泛型方法的定義
public class Pig {
public <T> void show(T t) {
System.out.println(t);
}
}
//泛型方法的使用
public class TestPig {
public static void main(String[] args) {
//1.創建對象
Pig p = new Pig();
//2.調用方法
p.<String>show("abc");
p.<Double>show(3.14);
}
}
iii.泛型接口:在接口上加泛型
//泛型接口的定義
public interface MyCollection<E> {
public abstract void setE(E e);
public abstract E getE();
}
//泛型接口有兩種確定泛型的方式
//a.實現類在實現接口時,確定泛型
class MyClass1 implements MyCollection<Integer>{
@Override
public void setE(Integer integer) {
}
@Override
public Integer getE() {
return null;
}
}
//b.實現類咋實現接口時,不確定泛型,實現類繼續保留泛型
class MyClass2<E> implements MyCollection<E>{
@Override
public void setE(E e) {
}
@Override
public E getE() {
return null;
}
}
//此時MyClass2<E>就是一個泛型類,回到泛型類的使用上
4.泛型通配符(泛型沒有多態)(<?>不加其實效果一樣)
泛型通配符:?代表任意泛型
public class TongPeiFuDemo {
public static void main(String[] args) {
//1.集合1
ArrayList<String> arr1 = new ArrayList<String>();
ArrayList<Integer> arr2 = new ArrayList<Integer>();
ArrayList<Double> arr3 = new ArrayList<Double>();
//2.調用方法
printArrayList(arr1);
printArrayList(arr2);
printArrayList(arr3);
//ArrayList<Object> arr = new ArrayList<String>();
}
//定義方法,接收一個集合
public static void printArrayList(ArrayList<?> arr){
}
5.泛型的上下限
ArrayList<?> 代表任意泛型的集合均可
上限:<? extends Animal>:代表泛型必須是Animal本類或者Animal的子類
下限:<? super Cat>:代表泛型必須是Cat本類或者Cat的父類
public class ShangXiaXianDemo {
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>();
//Object
// Number String
// Integer
getElement1(list1);
getElement1(list2);
getElement1(list3);
getElement1(list4);
getElement2(list1);
getElement2(list2);
getElement2(list3);
getElement2(list4);
}
// 泛型的上限:此時的泛型?,必須是Number類型或者Number類型的子類
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此時的泛型?,必須是Number類型或者Number類型的父類
public static void getElement2(Collection<? super Number> coll){}
}
四.集合綜合案例*******************
1.鬥地主案例介紹
2.鬥地主案例步驟分析
3.代碼實現
public class DouDiZhuDemo {
public static void main(String[] args) {
// 鬥地主案例步驟分析:
// 1.創建一副牌(54張)
ArrayList<String> cardBox = new ArrayList<String>();
String[] colors = {"♠", "♥", "♣", "♦"};
String[] nums = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
//嵌套循環
for (String color : colors) {
for (String num : nums) {
String card = color + num;
cardBox.add(card);
}
}
//大小王
cardBox.add("小王吧");
cardBox.add("大王吧");
// 2.洗牌(打亂順序)
//Collections 一種工具類 其中的方法都是靜態的
Collections.shuffle(cardBox);
// 3.發牌(輪流發給三個人,剩下3張)
ArrayList<String> p1 = new ArrayList<String>();
ArrayList<String> p2 = new ArrayList<String>();
ArrayList<String> p3 = new ArrayList<String>();
ArrayList<String> dp = new ArrayList<String>();
//發牌
for (int i = 0; i < cardBox.size() - 3; i++) {
//取出牌
String card = cardBox.get(i);
//發給誰????????????
// i = 0 3 6 p1
// i = 1 4 7 p2
// i = 2 5 8 p3
if (i % 3 == 0) {
p1.add(card);
} else if (i % 3 == 1) {
p2.add(card);
} else{
p3.add(card);
}
}
//底牌 53 52 51
dp.add(cardBox.get(51));
dp.add(cardBox.get(52));
dp.add(cardBox.get(53));
// 4.看牌(打印牌值)
System.out.println("令狐沖:"+p1);
System.out.println("田伯光:"+p2);
System.out.println("任盈盈:"+p3);
System.out.println("底 牌"+dp);
}
}
總結:
-[] 能夠說出集合與數組的區別
-[] 能夠使用Collection集合的常用功能
public boolean add(E e);
public boolean remove(E e);
public int size();
public boolean isEmpty();
public void clear();
public boolean contains(E e);
public Object[] toArray();
-[] 能夠使用迭代器對集合進行取元素
a.獲取迭代器 Iterator<E> it = 集合對象.iterator();
b.先判斷 boolean b = it.hasNext();
c.後取出 E e = it.next();
-[] 能夠使用增強for循環遍歷集合和數組
格式:
for(數據類型 變量名:數組/集合){
底層是迭代器
}
-[] 能夠使用集合存儲自定義類型
-[] 能夠使用泛型創建集合對象
-[] 能夠闡述泛型通配符的作用
-[] 能夠理解泛型上下限
上限:<? extends 類名>
下限:<? super 類名>
-[] 鬥地主案例**************