第五章 泛型&集合
阿新 • • 發佈:2020-07-16
5.1、泛型
概述:泛型是是JDK5中引入的特性,它提供了編譯時型別安全檢測機制,該機制允許在編譯時檢測到非法的型別,它的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。
泛型類:
// 格式:修飾符 class 類名<型別> { } class Generic<T> { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } } public class Main { public static void main(String[] args) { Generic<String> g1 = new Generic<String>(); g1.setT("String"); System.out.println(g1.getT()); Generic<Integer> g2 = new Generic<Integer>(); g2.setT(100); System.out.println(g2.getT()); Generic<Boolean> g3 = new Generic<Boolean>(); g3.setT(true); System.out.println(g3.getT()); } }
泛型方法:
// 格式:修飾符 <型別> 返回值型別 方法名(型別 變數名) { }
class Generic {
public <T> void show(T t) {
System.out.println(t);
}
}
public class Main {
public static void main(String[] args) {
Generic g = new Generic();
g.show("String");
g.show(100);
g.show(true);
}
}
泛型介面:
// 修飾符 interface 介面名<型別> { } interface Generic<T> { void show(T t); } class GenericImpl<T> implements Generic<T> { @Override public void show(T t) { System.out.println(t); } } public class Main { public static void main(String[] args) { Generic<String> g1 = new GenericImpl<String>(); g1.show("String"); Generic<Integer> g2 = new GenericImpl<Integer>(); g2.show(30); Generic<Boolean> g3 = new GenericImpl<Boolean>(); g3.show(true); } }
型別萬用字元:
型別萬用字元:<?>
List<?>:表示元素型別未知的List,它的元素可以匹配任何的型別
型別萬用字元上限:<? extends 型別>
List<? extends Number>:它表示的型別是Number或者其子型別
型別萬用字元下限:<? super 型別>
List<? super Number>:它表示的型別是Number或者其父型別
可變引數:
public class Main { public static void main(String[] args) { System.out.println(sum(10)); System.out.println(sum(10, 20)); System.out.println(sum(10, 20, 30)); System.out.println(sum(10, 20, 30, 40)); System.out.println(sum(10, 20, 30, 40, 50)); System.out.println(sum(10, 20, 30, 40, 50, 60)); System.out.println(sum(10, 20, 30, 40, 50, 60, 70)); System.out.println(sum(10, 20, 30, 40, 50, 60, 70, 80)); System.out.println(sum(10, 20, 30, 40, 50, 60, 70, 80, 90)); System.out.println(sum(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)); } // 格式:修飾符 返回值型別 方法名(資料型別… 變數名) { } public static int sum(int... a) { int sum = 0; for (int i : a) { sum += i; } return sum; } }
5.2、集合
概述:提供一種可變的儲存模型,儲存的資料容量可以隨時發生改變
體系:
5.2.1、Collection介面
子介面特點:
- List介面:按照順序存取,元素可以重複,有索引,可使用迭代器、增強for迴圈、普通for迴圈遍歷
- Set介面:不按照順序存取,元素不可以重複,沒有索引,可使用迭代器、增強for迴圈遍歷
通用方法:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
// 建立集合
Collection<String> collection = new ArrayList<String>();
// 新增元素
collection.add("張三");
collection.add("張三");
collection.add("李四");
collection.add("李四");
collection.add("王五");
collection.add("王五");
System.out.println(collection.toString());
// 移除元素
collection.remove("張三");
System.out.println(collection.toString());
// 判斷元素
boolean isContains = collection.contains("李四");
System.out.println(isContains);
// 判斷集合是否為空
boolean isEmpty = collection.isEmpty();
System.out.println(isEmpty);
// 獲取集合元素個數
int size = collection.size();
System.out.println(size);
// 用迭代器遍歷集合
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 用增強for迴圈遍歷
for (String s : collection) {
System.out.println(s);
}
// 新增另外集合元素
Collection<String> c = new ArrayList<String>();
c.add("小可愛");
c.add("大可愛");
collection.addAll(c);
System.out.println(collection.toString());
// 清空集合所有元素
collection.clear();
System.out.println(collection.toString());
}
}
5.2.2、List介面
子類特點:
- ArrayList集合:底層是陣列結構實現,查詢快、增刪慢
- LinkedList集合:底層是連結串列結構實現,查詢慢、增刪快
通用方法:
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Main {
public static void main(String[] args) {
// 建立集合
List<String> list = new ArrayList<String>();
// 新增元素
list.add("張三");
list.add("張三");
list.add("李四");
list.add("李四");
list.add("王五");
list.add("王五");
System.out.println(list.toString());
// List獨有方法:E get(int index)
String s = list.get(0);
System.out.println(s);
// List獨有方法:E set(int index, E element)
list.set(2, "xiaoqi");
System.out.println(list.toString());
// List獨有方法:ListIterator<E> listIterator()
ListIterator<String> listIterator = list.listIterator();
// 使用列表迭代器:從前向後迭代
while (listIterator.hasNext()) {
System.out.println(listIterator.next());
}
// 使用列表迭代器:從後向前迭代
while (listIterator.hasPrevious()) {
System.out.println(listIterator.previous());
}
// List獨有遍歷:普通for迴圈遍歷
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
注意事項:
LinkedList集合的特有方法:
方法 | 說明 |
---|---|
public void addFirst(E e) | 在該列表開頭插入指定的元素 |
public void addLast(E e) | 在該列表末尾追加指定的元素 |
public E getFirst() | 返回此列表中的第一個元素 |
public E getLast() | 返回此列表中的最後一個元素 |
public E removeFirst() | 從此列表中刪除並返回第一個元素 |
public E removeLast() | 從此列表中刪除並返回最後一個元素 |
5.2.3、Set介面
子類特點:
- HashSet集合:底層由雜湊表支撐,元素存取無序,物件新增需要重寫hashCode和equals方法
- TreeSet集合:底層由二叉樹支撐,元素順序存取,物件排序需要繼承Comparable介面重寫compareTo方法、或者使用Comparator初始化
HashSet演示:
import java.util.Collection;
import java.util.HashSet;
class Student {
private String name;
private Integer age;
public Student() {
super();
}
public Student(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((age == null) ? 0 : age.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class Main {
public static void main(String[] args) {
// 建立集合
Collection<Student> collection = new HashSet<Student>();
// 新增元素
collection.add(new Student("張三", 20));
collection.add(new Student("張三", 20));
collection.add(new Student("李四", 21));
collection.add(new Student("李四", 21));
collection.add(new Student("王五", 22));
collection.add(new Student("王五", 22));
System.out.println(collection.toString());
}
}
TreeSet演示:按照年齡從小到大排序,年齡相同時,按照姓名的字母順序排序
import java.util.Collection;
import java.util.Comparator;
import java.util.TreeSet;
class Student {
private String name;
private Integer age;
public Student() {
super();
}
public Student(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
public class Main {
public static void main(String[] args) {
// 建立集合
Collection<Student> collection = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 主要條件
int sort1 = s1.getAge() - s2.getAge();
// 次要條件
int sort2 = sort1 == 0 ? s1.getName().compareTo(s2.getName()) : sort1;
return sort2;
}
});
// 新增元素
collection.add(new Student("王五", 22));
collection.add(new Student("王五", 22));
collection.add(new Student("張三1", 20));
collection.add(new Student("張三0", 20));
collection.add(new Student("李四0", 18));
collection.add(new Student("李四1", 18));
System.out.println(collection.toString());
}
}
5.2.4、Map介面
介面特點:
- 鍵值對對映關係
- 一個鍵對應一個值,鍵不可以重複,值可以重複
- 凡是物件作為HashMap的鍵時,物件新增需要重寫hashCode和equals方法
通用方法:
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Main {
public static void main(String[] args) {
// 建立集合
Map<String, String> map = new HashMap<String, String>();
// 新增元素
map.put("呂布", "貂蟬");
map.put("項羽", "虞姬");
map.put("郭靖", "黃蓉");
map.put("後裔", "嫦娥");
System.out.println(map.toString());
// 刪除元素
map.remove("郭靖");
System.out.println(map.toString());
// 判斷集合是否包含指定鍵
boolean containsKey = map.containsKey("呂布");
System.out.println(containsKey);
// 判斷集合是否包含指定值
boolean containsValue = map.containsValue("貂蟬");
System.out.println(containsValue);
// 判斷集合是否為空
boolean isEmpty = map.isEmpty();
System.out.println(isEmpty);
// 獲取集合元素個數
int size = map.size();
System.out.println(size);
// 清空集合所有元素
map.clear();
System.out.println(map.toString());
// 新增另外集合元素
Map<String, String> m = new HashMap<String, String>();
m.put("張三", "李四");
m.put("王五", "小六");
map.putAll(m);
System.out.println(map.toString());
// 根據鍵獲取值
System.out.println(map.get("張三"));
// 獲取所有鍵的集合
Set<String> keySet = map.keySet();
// 迭代器遍歷
Iterator<String> keysIterator = keySet.iterator();
while (keysIterator.hasNext()) {
System.out.println(keysIterator.next());
}
// 增強for遍歷
for (String key : keySet) {
System.out.println(key);
}
// 獲取所有值的集合
Collection<String> values = map.values();
// 迭代器遍歷
Iterator<String> valuesIterator = values.iterator();
while (valuesIterator.hasNext()) {
System.out.println(valuesIterator.next());
}
// 增強for遍歷
for (String value : values) {
System.out.println(value);
}
// 獲取所有鍵值對物件的集合
Set<Entry<String, String>> entrySet = map.entrySet();
// 迭代器遍歷
Iterator<Entry<String, String>> entrySetIterator = entrySet.iterator();
while (entrySetIterator.hasNext()) {
Entry<String, String> entry = entrySetIterator.next();
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + ":" + value);
}
// 增強for遍歷
for (Entry<String, String> entry : entrySet) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + ":" + value);
}
}
}
5.3、Collections類
描述:是針對集合操作的工具類
成員方法:
方法 | 描述 |
---|---|
public static void sort(List list) | 將指定的列表按升序排序 |
public static void reverse(List list) | 反轉指定列表中元素的順序 |
public static void shuffle(List list) | 使用預設的隨機源隨機排列指定的列表 |
示例程式碼:鬥地主洗牌
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
// 建立HashMap,鍵是編號,值是牌面
HashMap<Integer, String> hm = new HashMap<Integer, String>();
// 建立ArrayList,儲存編號
ArrayList<Integer> array = new ArrayList<Integer>();
// 建立花色陣列和點數陣列
String[] colors = { "♦", "♣", "♥", "♠" };
String[] numbers = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2" };
// 從0開始往HashMap裡面儲存編號並存儲對應的牌面,同時往ArrayList裡面儲存編號
int index = 0;
for (String number : numbers) {
for (String color : colors) {
hm.put(index, color + number);
array.add(index);
index++;
}
}
hm.put(index, "小王");
array.add(index);
index++;
hm.put(index, "大王");
array.add(index);
// 洗牌(洗的是編號)
Collections.shuffle(array);
// 發牌(發的是編號)
TreeSet<Integer> playerSet1 = new TreeSet<Integer>();
TreeSet<Integer> playerSet2 = new TreeSet<Integer>();
TreeSet<Integer> playerSet3 = new TreeSet<Integer>();
TreeSet<Integer> dpSet = new TreeSet<Integer>();
for (int i = 0; i < array.size(); i++) {
int x = array.get(i);
if (i >= array.size() - 3) {
dpSet.add(x);
} else if (i % 3 == 0) {
playerSet1.add(x);
} else if (i % 3 == 1) {
playerSet2.add(x);
} else if (i % 3 == 2) {
playerSet3.add(x);
}
}
// 呼叫看牌方法
lookPoker("player1", playerSet1, hm);
lookPoker("player2", playerSet2, hm);
lookPoker("player3", playerSet3, hm);
lookPoker("dp", dpSet, hm);
}
/**
* 看牌方法
* @param name 玩家名稱
* @param ts 牌面編號
* @param hm 牌面集合
*/
public static void lookPoker(String name, TreeSet<Integer> ts, HashMap<Integer, String> hm) {
System.out.print(name + ": ");
for (Integer key : ts) {
String poker = hm.get(key);
System.out.print(poker + " ");
}
System.out.println();
}
}