Lambda表達(dá)式和Java集合框架
Java8為容器新增一些有用的方法,這些方法有些是為完善原有功能,有些是為引入函數(shù)式編程(Lambda表達(dá)式),學(xué)習(xí)和使用這些方法有助于我們寫(xiě)出更加簡(jiǎn)潔有效的代碼.本文分別以ArrayList和HashMap為例,講解Java8集合框架(Java Collections Framework)中新加入方法的使用.
前言
我們先從最熟悉的Java集合框架(Java Collections Framework, JCF)開(kāi)始說(shuō)起。
為引入Lambda表達(dá)式,Java8新增了java.util.funcion包
,里面包含常用的函數(shù)接口,這是Lambda表達(dá)式的基礎(chǔ),Java集合框架也新增部分接口,以便與Lambda表達(dá)式對(duì)接。
首先回顧一下Java集合框架的接口繼承結(jié)構(gòu):
上圖中綠色標(biāo)注的接口類(lèi),表示在Java8中加入了新的接口方法,當(dāng)然由于繼承關(guān)系,他們相應(yīng)的子類(lèi)也都會(huì)繼承這些新方法。下表詳細(xì)列舉了這些方法。
接口名 | Java8新加入的方法 |
---|---|
Collection | removeIf() spliterator() stream() parallelStream() forEach() |
List | replaceAll() sort() |
Map | getOrDefault() forEach() replaceAll() putIfAbsent() remove() replace() computeIfAbsent() computeIfPresent() compute() merge() |
這些新加入的方法大部分要用到j(luò)ava.util.function包下的接口,這意味著這些方法大部分都跟Lambda表達(dá)式相關(guān)。我們將逐一學(xué)習(xí)這些方法。
Collection中的新方法
如上所示,接口Collection和List新加入了一些方法,我們以是List的子類(lèi)ArrayList為例來(lái)說(shuō)明。了解Java7ArrayList實(shí)現(xiàn)原理,將有助于理解下文。
forEach()
該方法的簽名為void forEach(Consumer<? super E> action),作用是對(duì)容器中的每個(gè)元素執(zhí)行action指定的動(dòng)作,其中Consumer是個(gè)函數(shù)接口,里面只有一個(gè)待實(shí)現(xiàn)方法void accept(T t)(后面我們會(huì)看到,這個(gè)方法叫什么根本不重要,你甚至不需要記憶它的名字)。
需求:假設(shè)有一個(gè)字符串列表,需要打印出其中所有長(zhǎng)度大于3的字符串.
Java7及以前我們可以用增強(qiáng)的for循環(huán)實(shí)現(xiàn):
// 使用曾強(qiáng)for循環(huán)迭代 ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); for(String str : list){ if(str.length()>3) System.out.println(str); }
現(xiàn)在使用forEach()方法結(jié)合匿名內(nèi)部類(lèi),可以這樣實(shí)現(xiàn):
// 使用forEach()結(jié)合匿名內(nèi)部類(lèi)迭代 ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); list.forEach(new Consumer<String>(){ @Override public void accept(String str){ if(str.length()>3) System.out.println(str); } });
上述代碼調(diào)用forEach()方法,并使用匿名內(nèi)部類(lèi)實(shí)現(xiàn)Comsumer接口。到目前為止我們沒(méi)看到這種設(shè)計(jì)有什么好處,但是不要忘記Lambda表達(dá)式,使用Lambda表達(dá)式實(shí)現(xiàn)如下:
// 使用forEach()結(jié)合Lambda表達(dá)式迭代 ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); list.forEach( str -> { if(str.length()>3) System.out.println(str); });
上述代碼給forEach()方法傳入一個(gè)Lambda表達(dá)式,我們不需要知道accept()方法,也不需要知道Consumer接口,類(lèi)型推導(dǎo)幫我們做了一切。
removeIf()
該方法簽名為boolean removeIf(Predicate<? super E> filter),作用是刪除容器中所有滿足filter指定條件的元素,其中Predicate是一個(gè)函數(shù)接口,里面只有一個(gè)待實(shí)現(xiàn)方法boolean test(T t),同樣的這個(gè)方法的名字根本不重要,因?yàn)橛玫臅r(shí)候不需要書(shū)寫(xiě)這個(gè)名字。
需求:假設(shè)有一個(gè)字符串列表,需要?jiǎng)h除其中所有長(zhǎng)度大于3的字符串。
我們知道如果需要在迭代過(guò)程沖對(duì)容器進(jìn)行刪除操作必須使用迭代器,否則會(huì)拋出ConcurrentModificationException,所以上述任務(wù)傳統(tǒng)的寫(xiě)法是:
// 使用迭代器刪除列表元素 ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); Iterator<String> it = list.iterator(); while(it.hasNext()){ if(it.next().length()>3) // 刪除長(zhǎng)度大于3的元素 it.remove(); }
現(xiàn)在使用removeIf()方法結(jié)合匿名內(nèi)部類(lèi),我們可是這樣實(shí)現(xiàn):
// 使用removeIf()結(jié)合匿名名內(nèi)部類(lèi)實(shí)現(xiàn) ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); list.removeIf(new Predicate<String>(){ // 刪除長(zhǎng)度大于3的元素 @Override public boolean test(String str){ return str.length()>3; } });
上述代碼使用removeIf()方法,并使用匿名內(nèi)部類(lèi)實(shí)現(xiàn)Precicate接口。相信你已經(jīng)想到用Lambda表達(dá)式該怎么寫(xiě)了:
// 使用removeIf()結(jié)合Lambda表達(dá)式實(shí)現(xiàn) ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); list.removeIf(str -> str.length()>3); // 刪除長(zhǎng)度大于3的元素
使用Lambda表達(dá)式不需要記憶Predicate接口名,也不需要記憶test()方法名,只需要知道此處需要一個(gè)返回布爾類(lèi)型的Lambda表達(dá)式就行了。
replaceAll()
該方法簽名為void replaceAll(UnaryOperator<E> operator),作用是對(duì)每個(gè)元素執(zhí)行operator指定的操作,并用操作結(jié)果來(lái)替換原來(lái)的元素。其中UnaryOperator是一個(gè)函數(shù)接口,里面只有一個(gè)待實(shí)現(xiàn)函數(shù)T apply(T t)。
需求:假設(shè)有一個(gè)字符串列表,將其中所有長(zhǎng)度大于3的元素轉(zhuǎn)換成大寫(xiě),其余元素不變。
Java7及之前似乎沒(méi)有優(yōu)雅的辦法:
// 使用下標(biāo)實(shí)現(xiàn)元素替換 ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); for(int i=0; i<list.size(); i++){ String str = list.get(i); if(str.length()>3) list.set(i, str.toUpperCase()); }
使用replaceAll()方法結(jié)合匿名內(nèi)部類(lèi)可以實(shí)現(xiàn)如下:
// 使用匿名內(nèi)部類(lèi)實(shí)現(xiàn) ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); list.replaceAll(new UnaryOperator<String>(){ @Override public String apply(String str){ if(str.length()>3) return str.toUpperCase(); return str; } });
上述代碼調(diào)用replaceAll()方法,并使用匿名內(nèi)部類(lèi)實(shí)現(xiàn)UnaryOperator接口。我們知道可以用更為簡(jiǎn)潔的Lambda表達(dá)式實(shí)現(xiàn):
// 使用Lambda表達(dá)式實(shí)現(xiàn) ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); list.replaceAll(str -> { if(str.length()>3) return str.toUpperCase(); return str; });
sort()
該方法定義在List接口中,方法簽名為void sort(Comparator<? super E> c),該方法根據(jù)c指定的比較規(guī)則對(duì)容器元素進(jìn)行排序。Comparator接口我們并不陌生,其中有一個(gè)方法int compare(T o1, T o2)需要實(shí)現(xiàn),顯然該接口是個(gè)函數(shù)接口。
需求:假設(shè)有一個(gè)字符串列表,按照字符串長(zhǎng)度增序?qū)υ嘏判颉?/strong>
由于Java7以及之前sort()方法在Collections工具類(lèi)中,所以代碼要這樣寫(xiě):
// Collections.sort()方法 ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); Collections.sort(list, new Comparator<String>(){ @Override public int compare(String str1, String str2){ return str1.length()-str2.length(); } });
現(xiàn)在可以直接使用List.sort()方法,結(jié)合Lambda表達(dá)式,可以這樣寫(xiě):
// List.sort()方法結(jié)合Lambda表達(dá)式 ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too")); list.sort((str1, str2) -> str1.length()-str2.length());
spliterator()
方法簽名為Spliterator<E> spliterator(),該方法返回容器的可拆分迭代器。從名字來(lái)看該方法跟iterator()方法有點(diǎn)像,我們知道Iterator是用來(lái)迭代容器的,Spliterator也有類(lèi)似作用,但二者有如下不同:
- Spliterator既可以像Iterator那樣逐個(gè)迭代,也可以批量迭代。批量迭代可以降低迭代的開(kāi)銷(xiāo)。
- Spliterator是可拆分的,一個(gè)Spliterator可以通過(guò)調(diào)用Spliterator<T> trySplit()方法來(lái)嘗試分成兩個(gè)。一個(gè)是this,另一個(gè)是新返回的那個(gè),這兩個(gè)迭代器代表的元素沒(méi)有重疊。
可通過(guò)(多次)調(diào)用Spliterator.trySplit()方法來(lái)分解負(fù)載,以便多線程處理。
stream()和parallelStream()
stream()和parallelStream()分別返回該容器的Stream視圖表示,不同之處在于parallelStream()返回并行的Stream。Stream是Java函數(shù)式編程的核心類(lèi),我們會(huì)在后面章節(jié)中學(xué)習(xí)。
Map中的新方法
相比Collection,Map中加入了更多的方法,我們以HashMap為例來(lái)逐一探秘。了解Java7HashMap實(shí)現(xiàn)原理,將有助于理解下文。
forEach()
該方法簽名為void forEach(BiConsumer<? super K,? super V> action),作用是對(duì)Map中的每個(gè)映射執(zhí)行action指定的操作,其中BiConsumer是一個(gè)函數(shù)接口,里面有一個(gè)待實(shí)現(xiàn)方法void accept(T t, U u)。BinConsumer接口名字和accept()方法名字都不重要,請(qǐng)不要記憶他們。
需求:假設(shè)有一個(gè)數(shù)字到對(duì)應(yīng)英文單詞的Map,請(qǐng)輸出Map中的所有映射關(guān)系.
Java7以及之前經(jīng)典的代碼如下:
// Java7以及之前迭代Map HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for(Map.Entry<Integer, String> entry : map.entrySet()){ System.out.println(entry.getKey() + "=" + entry.getValue()); }
使用Map.forEach()方法,結(jié)合匿名內(nèi)部類(lèi),代碼如下:
// 使用forEach()結(jié)合匿名內(nèi)部類(lèi)迭代Map HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.forEach(new BiConsumer<Integer, String>(){ @Override public void accept(Integer k, String v){ System.out.println(k + "=" + v); } });
上述代碼調(diào)用forEach()方法,并使用匿名內(nèi)部類(lèi)實(shí)現(xiàn)BiConsumer接口。當(dāng)然,實(shí)際場(chǎng)景中沒(méi)人使用匿名內(nèi)部類(lèi)寫(xiě)法,因?yàn)橛蠰ambda表達(dá)式:
// 使用forEach()結(jié)合Lambda表達(dá)式迭代Map HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.forEach((k, v) -> System.out.println(k + "=" + v)); }
getOrDefault()
該方法跟Lambda表達(dá)式?jīng)]關(guān)系,但是很有用。方法簽名為V getOrDefault(Object key, V defaultValue),作用是按照給定的key查詢Map中對(duì)應(yīng)的value,如果沒(méi)有找到則返回defaultValue。使用該方法程序員可以省去查詢指定鍵值是否存在的麻煩.
需求;假設(shè)有一個(gè)數(shù)字到對(duì)應(yīng)英文單詞的Map,輸出4對(duì)應(yīng)的英文單詞,如果不存在則輸出NoValue
// 查詢Map中指定的值,不存在時(shí)使用默認(rèn)值 HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); // Java7以及之前做法 if(map.containsKey(4)){ // 1 System.out.println(map.get(4)); }else{ System.out.println("NoValue"); } // Java8使用Map.getOrDefault() System.out.println(map.getOrDefault(4, "NoValue")); // 2
putIfAbsent()
該方法跟Lambda表達(dá)式?jīng)]關(guān)系,但是很有用。方法簽名為V putIfAbsent(K key, V value),作用是只有在不存在key值的映射或映射值為null時(shí),才將value指定的值放入到Map中,否則不對(duì)Map做更改.該方法將條件判斷和賦值合二為一,使用起來(lái)更加方便.
remove()
我們都知道Map中有一個(gè)remove(Object key)方法,來(lái)根據(jù)指定key值刪除Map中的映射關(guān)系;Java8新增了remove(Object key, Object value)方法,只有在當(dāng)前Map中key正好映射到value時(shí)才刪除該映射,否則什么也不做.
replace()
在Java7及以前,要想替換Map中的映射關(guān)系可通過(guò)put(K key, V value)方法實(shí)現(xiàn),該方法總是會(huì)用新值替換原來(lái)的值.為了更精確的控制替換行為,Java8在Map中加入了兩個(gè)replace()方法,分別如下:
- replace(K key, V value),只有在當(dāng)前Map中key的映射存在時(shí)才用value去替換原來(lái)的值,否則什么也不做.
- replace(K key, V oldValue, V newValue),只有在當(dāng)前Map中key的映射存在且等于oldValue時(shí)才用newValue去替換原來(lái)的值,否則什么也不做.
replaceAll()
該方法簽名為replaceAll(BiFunction<? super K,? super V,? extends V> function),作用是對(duì)Map中的每個(gè)映射執(zhí)行function指定的操作,并用function的執(zhí)行結(jié)果替換原來(lái)的value,其中BiFunction是一個(gè)函數(shù)接口,里面有一個(gè)待實(shí)現(xiàn)方法R apply(T t, U u).不要被如此多的函數(shù)接口嚇到,因?yàn)槭褂玫臅r(shí)候根本不需要知道他們的名字.
需求:假設(shè)有一個(gè)數(shù)字到對(duì)應(yīng)英文單詞的Map,請(qǐng)將原來(lái)映射關(guān)系中的單詞都轉(zhuǎn)換成大寫(xiě).
Java7以及之前經(jīng)典的代碼如下:
// Java7以及之前替換所有Map中所有映射關(guān)系 HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); for(Map.Entry<Integer, String> entry : map.entrySet()){ entry.setValue(entry.getValue().toUpperCase()); }
使用replaceAll()方法結(jié)合匿名內(nèi)部類(lèi),實(shí)現(xiàn)如下:
// 使用replaceAll()結(jié)合匿名內(nèi)部類(lèi)實(shí)現(xiàn) HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.replaceAll(new BiFunction<Integer, String, String>(){ @Override public String apply(Integer k, String v){ return v.toUpperCase(); } });
上述代碼調(diào)用replaceAll()方法,并使用匿名內(nèi)部類(lèi)實(shí)現(xiàn)BiFunction接口。更進(jìn)一步的,使用Lambda表達(dá)式實(shí)現(xiàn)如下:
// 使用replaceAll()結(jié)合Lambda表達(dá)式實(shí)現(xiàn) HashMap<Integer, String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.replaceAll((k, v) -> v.toUpperCase());
簡(jiǎn)潔到讓人難以置信.
merge()
該方法簽名為merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction),作用是:
- 如果Map中key對(duì)應(yīng)的映射不存在或者為null,則將value(不能是null)關(guān)聯(lián)到key上;
- 否則執(zhí)行remappingFunction,如果執(zhí)行結(jié)果非null則用該結(jié)果跟key關(guān)聯(lián),否則在Map中刪除key的映射.
參數(shù)中BiFunction函數(shù)接口前面已經(jīng)介紹過(guò),里面有一個(gè)待實(shí)現(xiàn)方法R apply(T t, U u).
merge()方法雖然語(yǔ)義有些復(fù)雜,但該方法的用方式很明確,一個(gè)比較常見(jiàn)的場(chǎng)景是將新的錯(cuò)誤信息拼接到原來(lái)的信息上,比如:
map.merge(key, newMsg, (v1, v2) -> v1+v2);
compute()
該方法簽名為compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction),作用是把remappingFunction的計(jì)算結(jié)果關(guān)聯(lián)到key上,如果計(jì)算結(jié)果為null,則在Map中刪除key的映射.
要實(shí)現(xiàn)上述merge()方法中錯(cuò)誤信息拼接的例子,使用compute()代碼如下:
map.compute(key, (k,v) -> v==null ? newMsg : v.concat(newMsg));
computeIfAbsent()
該方法簽名為V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
,作用是:只有在當(dāng)前Map中不存在key值的映射或映射值為null時(shí),才調(diào)用mappingFunction,并在mappingFunction執(zhí)行結(jié)果非null時(shí),將結(jié)果跟key關(guān)聯(lián).
Function是一個(gè)函數(shù)接口,里面有一個(gè)待實(shí)現(xiàn)方法R apply(T t).
computeIfAbsent()常用來(lái)對(duì)Map的某個(gè)key值建立初始化映射.比如我們要實(shí)現(xiàn)一個(gè)多值映射,Map的定義可能是Map<K,Set<V>>,要向Map中放入新值,可通過(guò)如下代碼實(shí)現(xiàn):
Map<Integer, Set<String>> map = new HashMap<>(); // Java7及以前的實(shí)現(xiàn)方式 if(map.containsKey(1)){ map.get(1).add("one"); }else{ Set<String> valueSet = new HashSet<String>(); valueSet.add("one"); map.put(1, valueSet); } // Java8的實(shí)現(xiàn)方式 map.computeIfAbsent(1, v -> new HashSet<String>()).add("yi");
使用computeIfAbsent()將條件判斷和添加操作合二為一,使代碼更加簡(jiǎn)潔.
computeIfPresent()
該方法簽名為V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction),作用跟computeIfAbsent()相反,即,只有在當(dāng)前Map中存在key值的映射且非null時(shí),才調(diào)用remappingFunction,如果remappingFunction執(zhí)行結(jié)果為null,則刪除key的映射,否則使用該結(jié)果替換key原來(lái)的映射.
這個(gè)函數(shù)的功能跟如下代碼是等效的:
// Java7及以前跟computeIfPresent()等效的代碼 if (map.get(key) != null) { V oldValue = map.get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) map.put(key, newValue); else map.remove(key); return newValue; } return null;
總結(jié)
- Java8為容器新增一些有用的方法,這些方法有些是為完善原有功能,有些是為引入函數(shù)式編程,學(xué)習(xí)和使用這些方法有助于我們寫(xiě)出更加簡(jiǎn)潔有效的代碼.
- 函數(shù)接口雖然很多,但絕大多數(shù)時(shí)候我們根本不需要知道它們的名字,書(shū)寫(xiě)Lambda表達(dá)式時(shí)類(lèi)型推斷幫我們做了一切.
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
- Java基礎(chǔ)之集合框架詳解
- 簡(jiǎn)單了解java集合框架LinkedList使用方法
- Java集合框架Collections原理及用法實(shí)例
- 通過(guò)實(shí)例學(xué)習(xí)Java集合框架HashSet
- JAVA集合框架工具類(lèi)自定義Collections集合方法
- java集合框架線程同步代碼詳解
- 基于Java中最常用的集合類(lèi)框架之HashMap(詳解)
- Java復(fù)習(xí)之集合框架總結(jié)
- Java集合框架LinkedList詳解及實(shí)例
- Java集合框架中迭代器Iterator解析
- Java集合的總體框架相關(guān)知識(shí)總結(jié)
相關(guān)文章
Spring MVC過(guò)濾器-登錄過(guò)濾的代碼實(shí)現(xiàn)
本篇文章主要介紹了Spring MVC過(guò)濾器-登錄過(guò)濾,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。2017-01-01Java初學(xué)者入門(mén)之繼承和多態(tài)
Java 面向?qū)ο缶幊逃腥筇匦裕悍庋b、繼承、多態(tài),學(xué)好繼承和多態(tài)是面向?qū)ο箝_(kāi)發(fā)語(yǔ)言中非常重要的一個(gè)環(huán)節(jié),這篇文章主要給大家介紹了關(guān)于Java初學(xué)者入門(mén)之繼承和多態(tài)的相關(guān)資料,需要的朋友可以參考下2021-07-07SpringBoot使用@Async注解可能會(huì)遇到的8大坑點(diǎn)匯總
SpringBoot中,@Async注解可以實(shí)現(xiàn)異步線程調(diào)用,用法簡(jiǎn)單,體驗(yàn)舒適,但是你一定碰到過(guò)異步調(diào)用不生效的情況,今天,我就列出90%的人都可能會(huì)遇到的8大坑點(diǎn),需要的朋友可以參考下2023-09-09Java-Redis-Redisson分布式鎖的功能使用及實(shí)現(xiàn)
這篇文章主要介紹了Java-Redis-Redisson-分布式鎖的功能使用及實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08Java數(shù)據(jù)結(jié)構(gòu)與算法入門(mén)實(shí)例詳解
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)與算法入門(mén)實(shí)例詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03IDEA mybatis-generator逆向工程生成代碼
這篇文章主要介紹了IDEA mybatis-generator逆向工程生成代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Java?Jar包項(xiàng)目?jī)?nèi)存設(shè)置方法舉例
這篇文章主要給大家介紹了關(guān)于Java?Jar包項(xiàng)目?jī)?nèi)存設(shè)置方法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-01-01java基礎(chǔ)之泛型知識(shí)點(diǎn)總結(jié)
這篇文章主要介紹了java基礎(chǔ)之泛型知識(shí)點(diǎn)總結(jié),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很好的幫助,需要的朋友可以參考下2021-04-04Java常用類(lèi)之字符串相關(guān)類(lèi)使用詳解
String、StringBuilder、StringBuffer類(lèi)是Java中常用的三個(gè)字符串相關(guān)類(lèi)。本文將通過(guò)示例為大家講解一下他們的用法,需要的可以參考一下2022-08-08