TreeSet集合
TreeSet集合特點
- 元素有序,這裏的順序不是指存儲和取出的順序,而是按照一定的規則進行排序,具體排序方式取決於構造方法
- TreeSet():根據其元素的自然排序進行排序
- TreeSet(Comparator comparator) :根據指定的比較器進行排序
- 沒有帶索引的方法,所以不能使用普通for循環遍歷
- 由於是Set集合,所以不包含重複元素的集合
自然排序Comparable的使用
●存儲學生對象並遍歷, 創建TreeSet集合使用無參構造方法
要求:按照年齡從小到大排序,年齡相同時,按照姓名的字母順序排序
-
public interface Comparable<T>
Collections.sort
(和Arrays.sort
)可以自動對實現此接口的對象進行列表(和數組)排序。 實現該接口的對象,可以使用如在鍵sorted map或作爲在元件sorted set ,而不需要指定一個comparator 。一類C的自然順序被說成是與equals一致當且僅當e1.compareTo(e2) == 0對每一個e1和C類e2相同的布爾值e1.equals(e2)。 請注意, null不是任何類的實例, e.compareTo(null)應該拋出一個NullPointerException即使e.equals(null)返回false 。
例子:
public class Student implements Comparable<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;
}
//重寫接口Comparable的方法,爲了集合中能夠按照年齡進行排序
@Override
public int compareTo(Student o) {
//年齡從小到大來排序
int num = this.age - o.age;
//年齡相同時,按字母的順序進行排序
int num2 = num==0?this.name.compareTo(o.name):num;
return num2;
}
}
public class SetDemo {
public static void main(String[] args) {
TreeSet<Student> st = new TreeSet<Student>();
Student s1 = new Student("zhangsan",32);
Student s2 = new Student("lisi",31);
Student s3 = new Student("hejin",37);
Student s4 = new Student("daoming",35);
Student s5 = new Student("xiaohan",27);
Student s6 = new Student("feizi",31);
st.add(s1);
st.add(s2);
st.add(s3);
st.add(s4);
st.add(s5);
st.add(s6);
for(Student i:st){
System.out.println(i.getName() + ":" + i.getAge());
}
}
}
效果:
結論
- 用TreeSet集合存儲自定義對象, 無參構造方法使用的是自然排序對元素進行排序的
- 自然排序, 就是讓元素所屬的類實現Comparable接口,重寫compareTo(T o)方法
- 重寫方法時, - 定要注意排序規則必須按照要求的主要條件和次要條件來寫
實現不重複的隨機數
public class ListDemo {
public static void main(String[] args) {
// Set<Integer> s = new HashSet<Integer>();
//會自然排序
Set<Integer> s = new TreeSet<Integer>();
//隨機數對象
Random r = new Random();
//集合數量不大於10
while (s.size()<10){
int num = r.nextInt(21);
s.add(num);
}
for (int i:s) {
System.out.println(i);
}
}
}
泛型
泛型概述
泛型:是JDK5中引入的特性,它提供了編譯時類型安全檢測機制,該機制允許在編譯時檢測到非法的類型
它的本質是參數化類型,也就是說所操作的數據類型被指定爲一個參數
一提到參數, 最熟悉的就是定義方法時有形參,然後調用此方法時傳遞實參。那麼參數化類型怎麼理解呢?
顧名思義,就是將類型由原來的具體的類型參數化,然後在使用/調用時傳入具體的類型
這種參數類型可以用在類、方法和接口中,分別被稱爲泛型類、泛型方法、泛型接口
泛型定義格式:
- <類型>: 指定一種類型的格式。這裏的類型可以看成是形參
- <類型1,類型2...>:指定多種類型的格式,多種類型之間用逗號隔開。這裏的類型可以看成是形參
- 將來具體調用時候給定的類型可以看成是實參,並且實參的類型只能是引用數據類型
例子:
Collection c = new ArrayList();
//使用泛型解決int和string混雜集合
Collection<String> c = new ArrayList<String>();
泛型的好處:
- 把運行時期的問題提前到了編譯期間
- 避免了強制類型轉換
泛型類
例子:
public class Generic<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
public class ListDemo {
public static void main(String[] args) {
Generic<String> s = new Generic<>();
s.setT("水滸");
System.out.println(s.getT());
Generic<Integer> n = new Generic<>();
n.setT(100);
System.out.println(s.getT());
}
}
結果:
泛型方法
public class Generic {
public <T> void show(T t){
System.out.println(t);
}
}
public class ListDemo {
public static void main(String[] args) {
Generic g = new Generic();
g.show("李牧");
g.show(100);
g.show(true);
g.show(12.56);
}
}
結果:
類型通配符
爲了表示各種泛型List的父類,可以使用類型通配符
- 類型通配符: <?>
- List<?>:表示元素類型未知的List,它的元素可以匹配任何的類型
- 這種帶通配符的List僅表示它是各種泛型List的父類,並不能把元素添加到其中
如果說我們不希望List<?>是任何泛型List的父類,只希望它代表某一類泛型List的父類, 可以使用類型通配符的上限
- 類型通配符上限: <? extends類型>
- List<? extends Number>:它表示的類型是Number或者其子類型
除了可以指定類型通配符的上限,我們也可以指定類型通配符的下限
- 類型通配符 下限: <?super 類型>
- List<? super Number>:它表示的類型是Number或者其父類型
例子:
public class ListDemo {
public static void main(String[] args) {
//類型通配符: <?>
List<?> list1 = new ArrayList<Object>();
List<?> list2 = new ArrayList<Number>();
List<?> list3 = new ArrayList<Integer>();
//類型通配符上限: <? extends類型>
List<? extends Number> list4 = new ArrayList<Integer>();
//類型通配符 下限: <?super 類型>
List<? super Number> list5 = new ArrayList<Object>();
}
}
可變參數
可變參數又稱參數個數可變,用作方法的形參出現,那麼方法參數個數就是可變的了
- 格式:修飾符返回值類型方法名(數據類型..變量名{ }
- 範例: public static int sum(int...a){ }
例子:
public class ListDemo {
public static void main(String[] args) {
System.out.println(Sum(10,20));
System.out.println(Sum(10,20,30));
System.out.println(Sum(10,20,30,40,50));
}
public static int Sum(int ...a){
//將數據變成了一個數組,輸出a是數組地址
System.out.println(a);
int sum=0;
for(int i:a){
sum+=i;
}
return sum;
}
}
結果:
Map
-
public interface Map<K,V>
將鍵映射到值的對象。 地圖不能包含重複的鍵; 每個鍵可以映射到最多一個值。這個接口取代了Dictionary類,它是一個完全抽象的類而不是接口。
Map界面提供了三個集合視圖 ,允許將映射內容視爲一組鍵,值集合或鍵值映射集合。 地圖的順序被定義爲其中在地圖上的集合視圖迭代返回元素的順序。 一些地圖實現,如TreeMap課程,對他們的訂單做出了具體的保證; 其他人,像HashMap班,不要。
注意:如果使用可變對象作爲地圖鍵,必須非常小心。 如果對象的值以影響equals比較的方式更改,而對象是地圖中的鍵,則不會指定地圖的行爲。 這個禁令的一個特殊情況是,地圖不允許將自己包含在內。 雖然地圖可以將其本身作爲一個值,但建議您非常小心: equals和hashCode方法在這樣的地圖上已經不太明確。
所有通用映射實現類應提供兩個“標準”構造函數:一個創建空映射的void(無參數)構造函數,以及一個具有類型爲Map的單個參數的構造函數 ,它創建一個具有相同鍵值的新映射映射作爲參數。 實際上,後一個構造函數允許用戶複製任何地圖,產生所需類的等效地圖。 沒有辦法強制執行此建議(因爲接口不能包含構造函數),而JDK中的所有通用映射實現都符合要求。
創建Map集合的對象
- 多態的方式
- 具體的實現類HashMap
例子:(注意在map中鍵是唯一的)
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
//創建map集合對象
Map<String,String> map = new HashMap<String,String>();
//添加對象使用put方法
map.put("map1","天地");
map.put("map2","玄黃");
map.put("map3","宇宙");
map.put("map4","洪荒");
System.out.println(map);
}
}
結果:
Map集合的遍歷:
- 獲取所有鍵值對對象的集合
- Set<Map. Entry<K,V>> entrySet(): 獲取所有鍵值對對象的集合
- 遍歷鍵值對對象的集合,得到每一個鍵值對對象
- 用增強for實現,得到每一個Map.Entry
- 根據鍵值對對象獲取鍵和值
- 用getKey()得到鍵
- 用getValue()得到值
例子:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
//創建map集合對象
Map<String,String> map = new HashMap<String,String>();
//添加對象使用put方法
map.put("map1","天地");
map.put("map2","玄黃");
map.put("map3","宇宙");
map.put("map4","洪荒");
//獲取所有鍵值集合的對象
Set<Map.Entry<String,String>> entrySet = map.entrySet();
//遍歷鍵值對象的集合,得到每一個簡直對象
for(Map.Entry<String,String> i:entrySet){
//根據鍵值對象獲取鍵和值
String key = i.getKey();
String value = i.getValue();
System.out.println(key+":"+value);
}
}
}
結果:
HashMap嵌套ArrayList
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
//創建HashMap集合
HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();
//創建Arraylist集合,並添加元素
ArrayList<String> sgyy = new ArrayList<String>();
sgyy . add( "諸葛亮");
sgyy. add("趙雲");
//把ArrayL ist作爲元素添加到HashMap集合
hm. put("三國演義" ,sgyy);
ArrayList<String> xyj = new ArrayList<String>();
xyj. add("唐僧");
xyj. add("孫悟空");
//把ArrayL ist作爲元素添加到HashMap集合
hm. put("西遊記",xyj);
ArrayList<String> shz = new ArrayList<String>();
shz . add("武松");
shz.add("魯智深");
//把ArrayL ist作爲元素添加到HashMap集合
hm. put("水滸傳",shz);
//遍歷HashMap集合
Set<String> keySet = hm. keySet();
for(String key : keySet) {
System.out.println(key);
ArrayList<String> value = hm.get(key);
for (String s : value) {
System.out.println("\t" + s);
}
}
}
}
結果:
案例: 統計字符串中每個字符出現的次數
需求:鍵盤錄入一個字符串,要求統計字符串中每個字符串出現的次數。
舉例:鍵盤錄入"aababcabcdabcde"
在控制檯輸出: "a(5)b(4)c(3)d(2)e(1)"
思路:
- ①鍵盤錄入一個字符串
- ②創建HashMap集合,鍵是Character, 值是Integer
- ③遍歷字符串,得到每一個字符
- ④拿得到的每一個字符作爲鍵 到HashMap集合中去找對應的值,看其返回值
- 如果返回值是null:說明該字符在HashMap集合中不存在,就把該字符作爲鍵,1作爲值存儲
- 如果返回值不是null:說明該字符在HashMap集合中存在,把該值加1,然後重新存儲該字符和對應的值
- ⑤遍歷HashMap集合,得到鍵和值,按照要求進行拼接
- ⑥輸出結果
代碼:
public class MapDemo {
public static void main(String[] args) {
//鍵盤錄入一個字符串
Scanner sc = new Scanner(System. in);
System.out.println("請輸入一個字符串: ");
String line = sc.nextLine();
//創建HashMap集合,鍵是Character, 值是Integer
HashMap<Character, Integer> hm = new HashMap<Character, Integer>();
//遍歷字符串,得到每一個字符
for (int i = 0; i < line.length(); i++) {
char key = line.charAt(i);
//拿得到的每一個字符作爲鍵到HashMap集合中去找對應的值,看其返回值
Integer value = hm.get(key);
if (value == null) {
//如果返回值是null: 說明該字符在HashMap集合中不存在,就把該字符作爲鍵,1作爲值存儲
hm.put(key, 1);
} else {
//如果返回值不是null:說明該字符在HashMap集合中存在,把該值加1,然後重新存儲該字符和對應的值
value++;
hm.put(key, value);
}
}
//遍歷HashMap集合,得到鍵和值,按照要求進行拼接
StringBuilder sb = new StringBuilder();
Set<Character> keySet = hm.keySet();
for(Character key : keySet) {
Integer value = hm. get(key);
sb.append(key).append("(").append(value).append(")");
}
System.out.println(sb);
}
}
結果:
Collections
-
public class Collections extends Object
此類僅由靜態方法組合或返回集合。 它包含對集合進行操作的多態算法,“包裝器”,返回由指定集合支持的新集合,以及其他一些可能的和最終的。如果提供給它們的集合或類對象爲null,則此類的方法都拋出一個NullPointerException 。
該類中包含的多態算法的文檔通常包括實現的簡要說明 。 這些描述應被視爲實施說明 ,而不是說明書的一部分 。 只要規範本身得到遵守,實現者就可以隨意替代其他算法。 (例如,sort使用的算法不一定是一個mergeesort,但它必須是穩定的 。)
Collections類的概述
- 是針對集合操作的工類
Collections類的常用方法
- public static <T extends Comparable<? super T>> void sort(List<T> list): 將指定的列表按升序排序
- public static void reverse(List<?> list): 反轉指定列表中元素的順序
- public static void shuffle(List<?> list):使用默認的隨機源隨機排列指定的列表
例子:
public class MapDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
//添加元素
list.add(30);
list.add(20);
list.add(50);
list.add(10);
list.add(40);
//public static <T extends Comparable<? super T>> void sort (List<T> list): 將指定的列表按升序排序
Collections.sort(list);
//public static void reverse (List<?> list): 反轉指定列表中元素的順序
Collections.reverse(list);
//public static void shuffle (List<?> list): 使用默認的隨機源隨機排列指定的列表
//Collections.shuffle(list);
System.out.println(list);
}
}
結果:
一起學習,一起進步 -.- ,如有錯誤,可以發評論