一、單列集合
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;
}
}
}
}