1. 泛型接口的使用
public static void main (String[] args){
//泛型接口
//格式: public interface 接口名<泛型類型>
}
//定義個接口
public interface inter<T>{
//定義個方法
public void show(T t);
}
//有個類實(shí)現(xiàn)了這個接口
//第一種方式--指定具體的泛型類型(推薦用這種)
public class Demo implements inter<String>{
public void show(String t){
System.out.println(t);
}
}
//第二種方式--并不指定具體的泛型類型--沒有必要在實(shí)現(xiàn)接口的時候給自己類加泛型
// class Demo1<T> implements inter<T>{
// public void show(T t){
// System.out.println(t);
// }
// }
2. 泛型高級之通配符
List<?>list = new ArrayList<String>();
//在我們有時創(chuàng)建集合的時候,并不一定知道我們接收的是什么類型的元素
//我們就可以用通配符,說明我們的集合可以接收任何類型數(shù)據(jù)
//所以當(dāng)右邊是不確定泛型的時候,左邊可以用通配符
//注意左邊不是用Object匹配的--這樣左右泛型是不一致的
3. 增強(qiáng)for循環(huán)—底層依賴的是迭代器
//增強(qiáng)for循環(huán)遍歷--和iOS中的for(in)遍歷效果一樣
int[] arr = {11,4,444,55,55,66,65,32};
//快捷鍵:fore
for (int i : arr){
System.out.println(i);
}
System.out.println("-------------------");
String[] arr1 = {"dd","我是shei","帥哥","美女","老司機(jī)"};
for (String str : arr1){
System.out.println(str);
}
4.
//三種遍歷方法可否刪除
/*
* 1.普通for循環(huán):可以刪除
* 2.迭代器:可以刪除,但是必須使用迭代器自身的remove方法,否則會有并發(fā)修改錯誤
* 3.增強(qiáng)for循環(huán)--不能刪除
* */
//1.普通for循環(huán)
ArrayList<String> list = new ArrayList();
list.add("qq");
list.add("jj");
list.add("jj");
list.add("jj");
list.add("pp");
list.add("uu");
for (int i = 0; i < list.size(); i++){
if ("jj".equals(list.get(i))) {
//list.remove(i);//普通for循環(huán)可以直接刪除
//看了這個普通for循環(huán)進(jìn)行刪除的原理后,你就會明白如果我們的數(shù)據(jù)是挨著的,那么會出現(xiàn)漏刪的情況
//這是因?yàn)楫?dāng)我們執(zhí)行一次remove操作后,在ArrayList集合中的元素會整體向上移動,而i作為索引是加1的
//這樣的話,如果我們刪除中的有緊挨著的重復(fù)元素,就會出現(xiàn)漏刪
//解決辦法是,在刪除完成后,將i的索引回退一位
list.remove(i--);
}
}
System.out.println(list);
System.out.println("1---------------------");
//2.迭代器遍歷
list.add("89");
ListIterator it = list.listIterator();
while (it.hasNext()){
if ("uu".equals(it.next())){
it.remove();
}
}
System.out.println(list);
System.out.println("2-----------------------");
//3.增強(qiáng)for循環(huán)
list.add("tmac");
for (String str : list) {
if ("tamc".equals(str)){
list.remove("tamc");//增強(qiáng)for循環(huán)底層依賴的是迭代器,所以是無法刪除的,會引起并發(fā)修改異常
}
}
System.out.println(list);
5. 可變參數(shù)方法
//可變參數(shù)
int[] arr = {11,44,43,23,54,65};
//使用可變參數(shù)方法:
print(22,33,44,55);//這就是使用可變參數(shù)方法的強(qiáng)大之處
System.out.println("-------------------------");
print();//對于可變參數(shù),可以傳入的元素個數(shù)是0到無窮大
}
//正常方法我們傳一個數(shù)組
// public static void print(int[] arr){
// for (int i : arr){
// System.out.println(i);
// }
// }
//可變參數(shù)方法(我們?nèi)绻蛔⑨屔厦娴姆椒ǎ覀儗懮线@個可變參數(shù)的方法就會報(bào)錯,說明我們可變參數(shù)方法
// 給的參數(shù)和上面的參數(shù)是一樣的。 事實(shí)也是這樣的:就是這個int...就相當(dāng)于int數(shù)組,前面是什么類型,就是什么數(shù)組)
public static void print(int...arr){
for (Object ob : arr){
System.out.println(ob);
}
}
6. 集合轉(zhuǎn)數(shù)組,數(shù)組轉(zhuǎn)集合
//asList工具的使用
//1.數(shù)組轉(zhuǎn)集合--雖然不能增加和減少,但是可以用集合中的其它方法,集合的方法比數(shù)組豐富很多
String[] arrs = {"tmac","kobe","jj","sout","souf"};
List<String> list = Arrays.asList(arrs);
System.out.println(list);
System.out.println("1---------------------------");
//數(shù)組轉(zhuǎn)集合的好處--以為可以增加元素等操作,結(jié)果不行
// list.add("jjtmac");
// System.out.println(list);
//報(bào)錯:java.lang.UnsupportedOperationException不支持更改異常
//2.再來個int類型的數(shù)組,轉(zhuǎn)為集合
int[] arrI = {12,44,53,68,35,89,3};
List list1 = Arrays.asList(arrI);
//List<int> list2 = Arrays.asList(arrI);//這里我們給集合加個int的泛型是不行的,因?yàn)檫@里的泛型類型是int[]
System.out.println(list1);
//這里打印出來是一個地址值,是因?yàn)檫@里是將int[]整個數(shù)組作為一個元素加入到集合中
//對于基本數(shù)據(jù)類型數(shù)組轉(zhuǎn)為集合會被弄成一個對象,必須是引用數(shù)據(jù)類型的
Integer[] ite = {11,44,664,664,2222,22};
List<Integer> list2 = Arrays.asList(ite);
System.out.println(list2);
System.out.println("2------------------");
//3.集合轉(zhuǎn)數(shù)組
ArrayList<String> list3 = new ArrayList();
list3.add("a");
list3.add("b");
list3.add("c");
list3.add("d");
//這個方法里要求我們傳入一個String[] 的對象
String[] strarr = list3.toArray(new String[0]);
//這里我們給String[0]:傳入的長度小于等于集合的size就好,超過的話,多余的位置就是null
for (String str : strarr){
System.out.println(str);
}
7. ArrayList嵌套ArrayList
//ArrayList嵌套ArrayList
//集合中放集合
ArrayList<ArrayList<Student>> list = new ArrayList<>();//放有班級的大集合
ArrayList<Student> firstList = new ArrayList<>();//創(chuàng)建第一個由學(xué)生組成的班級
//給第一個班級添加人
firstList.add(new Student("tamc",19));
firstList.add(new Student("jj",34));
firstList.add(new Student("jkkj",98));
firstList.add(new Student("jsh",87));
ArrayList<Student> secondList = new ArrayList<>();//創(chuàng)建第二個由學(xué)生組成的班級
//給第二個班級添加人
secondList.add(new Student("kobe",19));
secondList.add(new Student("linek",34));
secondList.add(new Student("huohude",98));
secondList.add(new Student("love",87));
//我們大集合添加每個班級集合
list.add(firstList);
list.add(secondList);
//遍歷--循環(huán)嵌套循環(huán)遍歷
for (ArrayList<Student> listS : list){
for (Student s : listS){
System.out.println(s);
}
}
8. Set集合子類學(xué)習(xí)
//HashSet學(xué)習(xí)--Set集合沒有索引,不可以存儲重復(fù)值,存取無序
HashSet<String> hs = new HashSet<>();
boolean b1 = hs.add("a");
boolean b2 = hs.add("a");//因?yàn)镾et集合不能存儲重復(fù)元素,所以b2返回應(yīng)該為false
hs.add("b");
hs.add("c");
hs.add("d");
System.out.println(hs);
//用增強(qiáng)for循環(huán)遍歷
for (String str : hs){//只要能用迭代器遍歷的,都可以用增強(qiáng)for循環(huán)
System.out.println(str);
}
//方法都和List一模一樣的
9. 用Set存儲自定義對象,看其如何保證元素唯一性
//用存儲自定義對象驗(yàn)證HashSet如何保證元素唯一
HashSet<Student> hs = new HashSet<>();
hs.add(new Student("tmac",34));
hs.add(new Student("jjjj",34));
hs.add(new Student("kobe",78));
hs.add(new Student("jing",76));
hs.add(new Student("kine",34));
hs.add(new Student("kine",34));
hs.add(new Student("kine",34));
hs.add(new Student("kine",34));
//我們添加了幾個感覺是重復(fù)的學(xué)生對象
//打印hs的size,我們發(fā)現(xiàn)為7,說明這個所有都存進(jìn)來了,
System.out.println(hs.size());
System.out.println(hs);
//接下來給你解釋這個存儲原理
/*
* 我們舉例,想hs中存入一個Student對象,就像我們上火車一樣。
* 我們都要找個位置坐,第一個上來的tmac找個位置坐,它的位置號碼是根據(jù)其地址值算出的hashCode決定的
*然后其它人依次上了,到kine,我們添加了很多個重復(fù)的kine。但是他們的hashCode都是不一樣的。所以,HashSet認(rèn)為
* 他們都是不一樣的東西,就不會認(rèn)作是重復(fù)值
* 我們在Student類中作一個操作:重寫其hashCode方法,統(tǒng)一返回一個數(shù)。
*這個效果就好比,大家的火車座位號都是一樣的。那么我們就只能根據(jù)表面現(xiàn)象,看看哪些是不一樣的對象
*然后我們也重寫了Student類的equals方法,只比較對象的字面值
* */
@Override
public boolean equals(Object obj){
System.out.println("equals調(diào)用了");
//比較字面值,不比較地址
Student s = (Student)obj;
if (this.name.equals(s.name) && this.age == s.age){
return true;
}else{
return false;
}
}
@Override
public int hashCode() {
//return 100;
return this.name.hashCode() + this.age;
}
//針對這個hashCode的返回值,如果我們都返回一樣的,那我們無論加什么對象,
//都會去調(diào)用一下equals方法。這樣不是很好,如果我們返回屬性值,那么就相當(dāng)于
//先比較一次屬性值,那么就會少調(diào)用幾次equals方法了
10. LinkedHashSet概述和使用
//LinkedHashSet的使用:底層是鏈表實(shí)現(xiàn)的,是set中唯一一個怎么存怎么取的
//由于又是HashSet的子類,所以也可以保證元素唯一
LinkedHashSet<String> lin = new LinkedHashSet<>();
lin.add("a");
lin.add("b");
lin.add("c");
lin.add("d");
lin.add("c");
lin.add("a");
System.out.println(lin);