1-18 Collections工具类和StreamAPI流式编程
Map集合
PS:map集合中提供一個名詞【映射】
映射在數學中的解釋:
假設有A,B兩個非空集合,如果存在一個法則f,使得A中每個元素按照法則f在B中有唯一確定元素與之對應,則f為從A到B的映射即 f: A->B
上圖中映射關系是兩個集合的連接,從A集合連接到B集合,這個之間產生的關聯就是【映射】
A集合數據如何和B集合數據關聯在一起,映射關系提供了一種存儲方法**【key-value】 鍵值對**
映射關系中約束,作為key這一端的集合數據必須是唯一的且不允許重復
? 作為value這一端的集合數據可以不為唯一且可以重復
PS:就是因為這個原因key是唯一且不重復,所以把存儲key這邊集合會看做set集合
? value是不唯一且可以重復,所以把存儲value的這邊集合會看做List集合
嚴格上說Map并不是集合,而是把兩個集合之間產生了映射關系(Map接口并沒有繼承Collection),然而因為Map可以存儲數據,所以我們習慣把Map稱為集合
因為Map,沒有繼承Collection所有沒有Iterable接口,所以Map集合不提供迭代器遍歷,不支持普通for循環也不支持增強for循環
Map集合原則:key必須唯一且不允許重復,value可以不唯一且允許重復
例如:key1 = value1 key2 = value2 //上面這種結構是允許//下面這種不允許key1 = value1key1 = value2//此時就違反了key是唯一的原則,所以這樣操作是不允許Map集合的特點1.Map集合中是排重,它是根據key排重 2.key和value的類型必須是引用類型
Map集合的常用實現類HashMap
HashMap
基于哈希表的 Map 接口的實現。此實現提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順序恒久不變。
HashMap的常用方法
package com.qfedu.Map;import jdk.nashorn.internal.ir.CallNode;import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.function.BiFunction;/*HashMap的常用方法*/ public class HashMapAPIDemo {public static void main(String[] args) {//1.創建一個Map集合【默認容量是16 擴展因子0.75】//它有兩個泛型// 第一個泛型是key的泛型【存儲key的數據類型】// 第二個泛型是value的泛型【存儲value的數據類型】//無論是哪個泛型必須是引用類型HashMap<String,Integer> map = new HashMap<>();//它的構造方法中允許指定 初始容量 和 擴展因子// 它的構造方法還允許 通過傳入另外一個map集合對象對當前新建map對象進行初始化【將參中map集合對象kv值進行對創建map初始阿化】//常用API//1.向Map集合添加數據//第一個參數是要存儲的key,第二個參數是要存儲的valuemap.put("key1",1);//map集合已經重寫toString,所以可以直接打印System.out.println(map);//編譯和運行階段都不會報錯,而且是允許的,map依舊會保持key的唯一性//put方法的另外一個作用,就是覆蓋【修改】對應key存儲valuemap.put("key1",2);System.out.println(map);//Java8中提供了意外一種創建方式//向map集合集合中添加kv鍵值對,但是如果key存在則不添加, 否則添加kv鍵值map.putIfAbsent("key2",2);System.out.println(map);//Java8中提供這個方法的目的就是為了防止存儲數據時出現誤覆蓋的操作//PS:建議 對map集合存儲數據時候建議使用putIfAbsent 修改map中value建議使用put//將另外一個map集合中的數據添加到當前map結合putAll(map集合對象);//PS:依舊會根據key進行排重操作//清空集合 clear 清空集合中的數據,但是集合引用還在//Java8 compute的方法 提供key在map中進行操作/*PS:無論key是否存在后面Lambda表達式都會執行判斷第一個參數 即 key是否存在1.如果key存在,執行第二參數 lambda表達式 允許獲取出key和value的值,直接對取出的這個kv值進行擦操作這個操作會執行影響原有kv值2.如果key不存在,執行第二參數 lambda表達式,相當于對map進行賦值*/HashMap<String,Integer> map1 = new HashMap<>();map1.putIfAbsent("1",1);map1.putIfAbsent("2",1);map1.putIfAbsent("3",1);// 返回值是你從操作的value值Integer compute = map1.compute("3", (k, v) -> v == null ? 0 : v + 1);System.out.println(compute);System.out.println(map1);Integer compute1 = map1.compute("4", (k, v) -> v == null ? 0 : v + 1);System.out.println(compute1);System.out.println(map1);//computeIfAbsent 判斷key值執行lambda表達式/*如果參數key存在,后面lambda表達式就不會執行如果參數key不存在,后面lambda表達式就執行,并存儲到對應map集合中*/map1.computeIfAbsent("3",key -> new Integer(5));System.out.println(map1);map1.computeIfAbsent("5",key -> new Integer(5));System.out.println(map1);//computeIfPresent 判斷key執行對應lambda表達式/*1.如果key存在,就執行后面lambda表達式,修改對相應key的value值并得到這個返回值2.如果key不存在,就不會執行后面lambda表達式,不會像map集合添加元素,返回null*/map1.computeIfPresent("3",(k,v)->v+1);System.out.println(map1);map1.computeIfPresent("6",(k,v)->v+1);System.out.println(map1);//判斷map集合中是否存在指定key 存在則true 否則falseboolean key1 = map.containsKey("key1");//判斷map集合中是否存在指定的value 存在則true,否則falseboolean b = map.containsValue(2);//遍歷方式1 forEach方法【這個方法只能打印,不能做操作,沒有返回值】map.forEach((k,v)->{System.out.println("key的值是:"+k);System.out.println("value的值是:"+v);});//遍歷方式2: entrySet 方法會直接返回一個Set集合,這集合中存儲是一個個鍵值對對象/*Set<Map.Entry<String, Integer>>拆解 set<>集合的泛型是 Map.Entry<String,Integer> 對象 Entry對象是一個鍵值對*/Set<Map.Entry<String, Integer>> entries = map1.entrySet();System.out.println(entries);for (Map.Entry<String, Integer> entry:entries) {System.out.println(entry.getKey()+"--》"+entry.getValue());}//通過key獲取對應value值【如果key不存在這取出一個null】Integer integer = map.get("key1");//Java8中提供 getOrDefault 如果key存在著返回對象value值, key不存在返回一個默認值Integer integer1 = map.getOrDefault("key4", Integer.MIN_VALUE);System.out.println(integer1);//判斷集合是否為空 isEmpty 判斷集合中是否有數據//獲取map集合中所有key值存儲到Set集合匯總Set<String> strings = map.keySet();//merge 翻譯就是合并//對存在kv進行進行修改并更新kv值/*第一個參數是map集合中存在key第二個參數是賦值給lambda表達式中的第二個參數值第三個參數是lambda表達式,lambda需要兩個參數參數1 : 是第一個參數key所對應value --> oldVal 就是通過參數key獲取的value值參數2 : 是第二個參數的value -->newVal 第二個參數的值核心目的就是對這個value值進行操作,然后在重新賦值給對應kv鍵值查找map中key為1的value中,并修改value值+10*/map1.merge("1",10,(oldVal,newVal)->oldVal+newVal);map1.merge("2", 20, new BiFunction<Integer, Integer, Integer>() {@Overridepublic Integer apply(Integer integer, Integer integer2) {return integer+integer2;}});//刪除map集合中的鍵值對 參數是key值, 只要傳入key滿足條件 直接刪除整個鍵值對map.remove("key1");//判斷kv是否存在著刪除返回為true 不存在這不刪除返回false【少】boolean remove = map1.remove("6", 6);//Java8中提供replace方法就是為了替換put概念map1.replace("2",2); //key存在則替換,不存在著不替換System.out.println(map1);//了解 和上面同理//map1.replace("110",0,110);//System.out.println(map1);//通過lambda表達式指定替換條件,替換所有滿足條件kv鍵值對map1.replaceAll((key,value)->{ //key 和 value 會獲取到map集合中每一個鍵值對//指定替換條件if(key.length() >= 1){value = 1;}//這個實現必須有返回值,修改過后的valuereturn value;});System.out.println(map1);//size 獲取集合的長度【一共存儲了多少個鍵值對】System.out.println(map1.size());//獲取map集合中所有value值存儲到Collection集合匯總Collection<Integer> values = map.values();} }Map集合總結:
Map集合是獨立的,它不屬于Collection,Map集合提供了一種鍵值對的存儲機制【key-value】
key值必須唯一,value值可以不唯一
Map是接口說以提供實現類:【HashMap、LinkedHashMap、TreeMap】
主要使用實現方式就是HashMap:采用Hash算法, 此時Map中不保證key的添加順序,保證key的唯一【key保證唯一的方式使用equals和hashcode】
PS:建議Map的key放一個不易改變的數據類型
LinkedHashMap:采用類鏈表和Hash算法,此時保證Map中key的添加順序,key不允許重復,它是HashMap的子類,使用方式和HashMap是一樣的
Hashtable【不會再開發中使用了】,它也是使用hash算法實現,是HashMap的前身【類似于Vector與ArrayList之間的關系】Hashtable是線程安全效率低,HashMap線程不安全但是效率高
TreeMap:采用紅黑二叉樹進行存儲,TreeMap的排序是排序key而非value,所以需要使用TreeMap進行排序,需要將數據寫到key中。
package com.qfedu.Map;import java.util.TreeMap;public class TreeMapDemo {public static void main(String[] args) {TreeMap<Integer,String> treeMap = new TreeMap<>();treeMap.putIfAbsent(10,"1");treeMap.putIfAbsent(7,"1");treeMap.putIfAbsent(1,"1");treeMap.putIfAbsent(11,"1");treeMap.putIfAbsent(6,"1");treeMap.putIfAbsent(4,"1");System.out.println(treeMap);} }key值必須實現了Comparable或Compartor接口
因為整體常用Map都是線程不安全的,所以提供如下修改方式讓其線程安全
Collections.synchronizedMap(map對象); //得到一個線程安全的map集合Set集合作業
1.使用TreeSet實現雙色球
package com.qfedu.Set;import java.util.Random; import java.util.TreeSet;/*** 雙色球* 1、紅球隨機1-32 唯一且不允許重復并有序輸出【升序】* 2、藍球隨機1-16, 可以紅球重復 一個球即可【不參與排序】*/ public class DoubleBallDemo {public static void main(String[] args) {TreeSet<Integer> set = new TreeSet<>();// Random random = new Random();while(set.size() < 6){// int r = random.nextInt(32)+1;int r = ((int)(Math.random()*32)+1);set.add(r);}System.out.println("紅球:"+set);int b = new Random().nextInt(16)+1;System.out.println("藍球:"+b);} }2.向TreeSet集合中加入5個員工的對象,根據員工的年齡(升序)進行排序,若年齡相同,再根據工齡(降序)來排序,若工齡相同,根據薪水(降序)排序
這道題即可以使用Comparable也可以使用Comparator,但是不能兩個都使用
PS:
無論是哪個一個接口實現,萬能公式 當前對象.屬性-傳入對象.屬性【升序】 傳入對象.屬性-當前對象.屬性【降序】
如果實現Comparable接口那么就使用TreeSet無參構造方法
如果實現Comparator接口那么就是用TreeSet有參構造方法,并將Comparator實現類的對象傳入到構造方法
package com.qfedu.Set; //員工 public class Employee implements Comparable<Employee>{private String name;private int age;private int workerAge;private int money;public Employee() {}public Employee(String name, int age, int workerAge, int money) {this.name = name;this.age = age;this.workerAge = workerAge;this.money = money;}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;}public int getWorkerAge() {return workerAge;}public void setWorkerAge(int workerAge) {this.workerAge = workerAge;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", age=" + age +", workerAge=" + workerAge +", money=" + money +'}';}@Overridepublic int compareTo(Employee other) { // int subAge = this.age - other.age; // int subWorkerAge = other.workerAge - this.workerAge; // int subMoney = other.money - this.money; // int subName = this.name.compareTo(other.name); // // return subAge == 0 ? subWorkerAge : subAge;return this.age - other.age == 0 ?other.workerAge-this.workerAge == 0 ?other.money-this.money == 0 ?this.name.compareTo(other.name):other.money-this.money :other.workerAge-this.workerAge :this.age-other.age;} } package com.qfedu.Set;import java.util.Collections; import java.util.Comparator; import java.util.TreeSet;public class TreeSetDemo {public static void main(String[] args) { // TreeSet<Employee> set = new TreeSet<>(new Comparator<Employee>() { // @Override // public int compare(Employee o1, Employee o2) { // return 0; // } // }); // TreeSet<Employee> set = new TreeSet<>(((o1, o2) -> { // return o1.getAge()-o2.getAge(); // });TreeSet<Employee> set = new TreeSet<>();Collections.addAll(set,new Employee("張三",18,3,3000),new Employee("李四",18,2,5000),new Employee("王五",12,10,100000000),new Employee("趙六",30,1,4000),new Employee("田七",12,10,1));System.out.println(set);} }3.動物園
package com.qfedu.Set;public abstract class Animal {private int BigLongtui;public Animal(int BigLongtui){this.BigLongtui = BigLongtui;}public int getBigLongtui() {return BigLongtui;}public void setBigLongtui(int bigLongtui) {BigLongtui = bigLongtui;} }public class QQ extends Animal {public QQ(int BigLongtui){super(BigLongtui);}@Overridepublic String toString() {return "企鵝腿:"+getBigLongtui();} }public class Cat extends Animal {public Cat(int BigLongtui){super(BigLongtui);}@Overridepublic String toString() {return "貓腿:"+getBigLongtui();} }public class Yu extends Animal {public Yu(int BigLongtui){super(BigLongtui);}@Overridepublic String toString() {return "魚腿:"+getBigLongtui();} }public class TuiException extends Exception {public TuiException() {}public TuiException(String message) {super(message);}public TuiException(String message, Throwable cause) {super(message, cause);}public TuiException(Throwable cause) {super(cause);}public TuiException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);} }import java.util.Objects; import java.util.Scanner;public class AnimalSystem {public static void main(String[] args) {System.out.println("-------------------------歡迎來到紅浪漫動物園----------------------------");System.out.println("請輸要創建的動物:");Scanner input = new Scanner(System.in);String name = input.next();System.out.println("請輸入大長腿的個數:");int tui = input.nextInt();Animal animal = null;try {animal = createAnimal(name,tui);} catch (RuntimeException e) {System.out.println(e.getMessage());}try {boolean b = checkAnimalTui(animal);if (b){System.out.println("恭喜你男賓一位樓上請......");}} catch (TuiException e) {System.out.println(e.getMessage());}}private static boolean checkAnimalTui(Animal animal) throws TuiException {if(Objects.isNull(animal)){throw new TuiException("不好意不能用這個退");}if( animal instanceof Cat){Cat cat = (Cat)animal;if(cat.getBigLongtui() != 4){throw new TuiException("不好意不能用這個退");}else{return true;}}else if( animal instanceof QQ) {QQ qq = (QQ) animal;if (qq.getBigLongtui() != 2) {throw new TuiException("不好意不能用這個退");} else {return true;}}else {Yu yu = (Yu) animal;if (yu.getBigLongtui() != 0) {throw new TuiException("不好意不能用這個退");} else {return true;}}}private static Animal createAnimal(String name, int tui) {if(name.equals("貓")){return new Cat(tui);}else if(name.equals("企鵝")){return new QQ(tui);}else if(name.equals("魚")){return new Yu(tui);}else{throw new RuntimeException("不好意思本動物園沒有這個動物");}} }Map作業
1.一個人對應多張銀行卡 Card: cardNo:銀行卡號,startDate:開戶日期, money:余額
 請設計一個程序,輸入一個人的名稱,得到這個人的所有銀行卡信息。 鍵值對
2.詩詞系統
使用Map集合,完成一個圖書館詩詞查閱系統,程序運行效果如下:------------------ 國家圖書館詩詞查閱系統 -------------------請錄入您要查看的詩詞名:春曉 xxxx,xx,xxxx...還要繼續閱讀嗎?yes請錄入您要查看的詩詞名:沁園春.雪 作者:xxx 朝代:xx 內容:xxx xxxx,xx,xxxx...還要繼續閱讀嗎?no謝謝使用!^-^Collections工具類
Collections是一個工具類,這個類中封裝了多個處理Collection集合中方法
PS:Collections工具類主要是處理List和Set,少部分是處理Map
package com.qfedu.Collections;import java.util.*;/*Collections工具類使用*/ public class CollectionsAPI {public static void main(String[] args) {//Collection有兩個子類List和Set,所以只要參數類型是Collection那么list和set都可以使用//1.向Collection集合中一次添加多個值List<Integer> list = new ArrayList<>();Collections.addAll(list,432,5432,5423,62,572,72,16423,624,72,13,6535);//2.因為在Java8中List集合已經支持sort接口,所以Collections中這個方法的作用就減少//對List集合進行排序Collections.sort(list); // 升序System.out.println(list);//自定義升降序,需要實現Comparator接口 // Collections.sort(list,(o1,o2)->o2-o1); // System.out.println(list);//工具類提供了一個降序的實現【工具類提供了一個方法就方法已經實現了降序】Collections.sort(list,Collections.reverseOrder());System.out.println(list);//Collections工具類提供了二分查找[只能查找List集合]//找到下標 ,找不到負數int i = Collections.binarySearch(list, 92);//交換兩個元素的位置//參數 1. 要交換的List集合 第二、三個參數是要交換位置的下標Collections.swap(list,0,list.size()-1);//將集合中元素順序打亂Collections.shuffle(list);//必備技能【多線程并發訪問集合】,為了保證線程安全,在Java5之后Collections工具類中提供轉換線程全的集合方法//Collections.synchronizedXXXXXX() --> XXXXXX -->指當前參數屬于哪個集合這個XXXX就是哪個集合的父類【List,Set,Map】/*以下操作方式之后,得到的都是線程安全的集合,但是他們并不是 Vector,Hashtable ,而是一個線程安全的集合*/List<Integer> list1 = Collections.synchronizedList(new ArrayList<Integer>());// SynchronizedRandomAccessListSet<Integer> set1 = Collections.synchronizedSet(new HashSet<Integer>());Map<String, Integer> map1 = Collections.synchronizedMap(new HashMap<String, Integer>());} }List作業(斗地主)
package com.qfedu.List;import java.util.ArrayList; import java.util.Collections; import java.util.List;/* 撲克類*/ public class Poker {private static final String[] color = {"?","?","?","?"}; //花色private static final String[] num = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};//點數private static final String[] king = {"大?","小?"};//大小王//提供一個私有屬性【存所有的牌】private static List<String> listPoker = new ArrayList<>();//提供一個方法進行牌的存儲【將牌進行一個組合】public static void setPoker(){for (int i= 0;i<color.length;i++){//需要將花色和點數進行拼接for(int j = 0; j<num.length;j++){listPoker.add(color[i]+num[j]);}if(i<king.length){//i值只要在存儲范圍內,就可以利用i值當做存儲大小王數組的下標listPoker.add(king[i]);}}}//洗牌public static void flushPoker(){Collections.shuffle(listPoker);}//發牌/*p1 p2 p3 是三個玩家的手牌p4 剩余三張手牌*/public static void dealPoker(List<String> p1List,List<String> p2List,List<String> p3List,List<String> p4List){for(int i= 0 ; i<listPoker.size();i++){//每人一次張if( i < listPoker.size() -3){if(i%3 == 0){p1List.add(listPoker.get(i));}else if(i % 2 == 0){p2List.add(listPoker.get(i));}else{p3List.add(listPoker.get(i));}}else{p4List.add(listPoker.get(i));//剩余三張牌}}}}import java.util.ArrayList; import java.util.List;//玩家 public class Player {//名字private String name;//提供一個集合存儲手牌private List<String> pokers = new ArrayList<>();public Player(){}public Player(String name){this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<String> getPokers() {return pokers;}public void setPokers(List<String> pokers) {this.pokers = pokers;}//展示手牌public void shoInfosPoker(){System.out.println(name +":"+pokers);}}import java.util.Comparator;//排序規則 public class Relu implements Comparator<String> {@Overridepublic int compare(String o1, String o2) {// 花色 點數 和 大小王//處理的時候 2~10的字符串是最好處理, J Q K A 小王和大王 后一個大于前一個一位數字即可Integer i1;Integer i2;//點數和花色拆開String str1 = o1.substring(1);//當前對象的值 例如 紅2 --》拆分--》 2String str2 = o2.substring(1);//傳入對象的值if (str1.equals("J")){i1 = 11;}else if(str1.equals("Q")){i1 = 12;}else if(str1.equals("K")){i1 = 13;}else if(str1.equals("A")){i1 = 14;}else if(str1.equals("?")){i1=15;}else if(str1.equals("?")){i1 = 16;}else{i1 = new Integer(str1);}if (str2.equals("J")){i2 = 11;}else if(str2.equals("Q")){i2 = 12;}else if(str2.equals("K")){i2 = 13;}else if(str2.equals("A")){i2 = 14;}else if(str2.equals("?")){i2=15;}else if(str2.equals("?")){i2 = 16;}else{i2 = new Integer(str2);}return i1-i2;} }package com.qfedu.List;import com.sun.xml.internal.ws.addressing.WsaActionUtil;import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner;public class Test {public static void main(String[] args) throws InterruptedException {System.out.println("---------------------------------JJ斗地主-----------------------------------");System.out.println("正在洗牌.......");Poker.setPoker();Poker.flushPoker();Thread.sleep(2000);//卡頓效果Scanner input = new Scanner(System.in);System.out.println("請輸入三個玩家的姓名:");String name1 = input.next();String name2 = input.next();String name3 = input.next();//創建3個集合存儲玩家手牌List<String> p1List = new ArrayList<>();List<String> p2List = new ArrayList<>();List<String> p3List = new ArrayList<>();//存儲最后三張牌List<String> p4List = new ArrayList<>();System.out.println("進入發牌階段");Poker.dealPoker(p1List,p2List,p3List,p4List);Thread.sleep(1000);//需要對牌進行排序操作Collections.sort(p1List,new Relu());Collections.sort(p2List,new Relu());Collections.sort(p3List,new Relu());//設置玩家Player p1 = new Player(name1);Player p2 = new Player(name2);Player p3 = new Player(name3);p1.setPokers(p1List);p2.setPokers(p2List);p3.setPokers(p3List);System.out.println("展示玩家手牌:");p1.shoInfosPoker();p2.shoInfosPoker();p3.shoInfosPoker();System.out.println("請輸入要叫地主的玩家名稱:");String name4 = input.next();System.out.println("展示底牌:"+p4List);if(p1.getName().equals(name4)){p1List.addAll(p4List);Collections.sort(p1List,new Relu());}else if(p2.getName().equals(name4)){p2List.addAll(p4List);Collections.sort(p2List,new Relu());}else{p3List.addAll(p4List);Collections.sort(p3List,new Relu());}System.out.println("展示玩家手牌:");p1.shoInfosPoker();p2.shoInfosPoker();p3.shoInfosPoker();} }總結
以上是生活随笔為你收集整理的1-18 Collections工具类和StreamAPI流式编程的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 狼追击兔matlab,狼兔追击问题-数学
- 下一篇: Launcher3如何实现主菜单背景的透
