亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java8新特性之Stream使用詳解

 更新時間:2023年08月30日 11:01:21   作者:余生海  
這篇文章主要介紹了Java8新特性之Stream使用詳解,流是用來處理集合中的數(shù)據(jù),以聲明的形式操作集合,它就像SQL語句,我們只需告訴流需要對集合進(jìn)行什么操作,它就會自動進(jìn)行操作,并將執(zhí)行結(jié)果交給你,無需我們自己手寫代碼,需要的朋友可以參考下

一、Stream介紹

什么是流?

流是Java8引入的全新概念,它用來處理集合中的數(shù)據(jù),暫且可以把它理解為一種高級集合。

眾所周知,集合操作非常麻煩,若要對集合進(jìn)行篩選、投影,需要寫大量的代碼,而流是以聲明的形式操作集合,它就像SQL語句,我們只需告訴流需要對集合進(jìn)行什么操作,它就會自動進(jìn)行操作,并將執(zhí)行結(jié)果交給你,無需我們自己手寫代碼。

因此,流的集合操作對我們來說是透明的,我們只需向流下達(dá)命令,它就會自動把我們想要的結(jié)果給我們。

由于操作過程完全由Java處理,因此它可以根據(jù)當(dāng)前硬件環(huán)境選擇最優(yōu)的方法處理,我們也無需編寫復(fù)雜又容易出錯的多線程代碼了。

流的特點

  • 只能遍歷一次

我們可以把流想象成一條流水線,流水線的源頭是我們的數(shù)據(jù)源(一個集合),數(shù)據(jù)源中的元素依次被輸送到流水線上,我們可以在流水線上對元素進(jìn)行各種操作。

一旦元素走到了流水線的另一頭,那么這些元素就被“消費掉了”,我們無法再對這個流進(jìn)行操作。

當(dāng)然,我們可以從數(shù)據(jù)源那里再獲得一個新的流重新遍歷一遍。

  • 采用內(nèi)部迭代方式

若要對集合進(jìn)行處理,則需我們手寫處理代碼,這就叫做外部迭代。

而要對流進(jìn)行處理,我們只需告訴流我們需要什么結(jié)果,處理過程由流自行完成,這就稱為內(nèi)部迭代。

流的操作種類

流的操作分為兩種,分別為中間操作和終端操作。

  • 中間操作

當(dāng)數(shù)據(jù)源中的數(shù)據(jù)上了流水線后,這個過程對數(shù)據(jù)進(jìn)行的所有操作都稱為“中間操作”。 中間操作仍然會返回一個流對象,因此多個中間操作可以串連起來形成一個流水線。

  • 終端操作

當(dāng)所有的中間操作完成后,若要將數(shù)據(jù)從流水線上拿下來,則需要執(zhí)行終端操作。 終端操作將返回一個執(zhí)行結(jié)果,這就是你想要的數(shù)據(jù)。 流的操作過程

使用流一共需要三步:

  1. 準(zhǔn)備一個數(shù)據(jù)源
  2. 執(zhí)行中間操作
    中間操作可以有多個,它們可以串連起來形成流水線。
  3. 執(zhí)行終端操作
    執(zhí)行終端操作后本次流結(jié)束,你將獲得一個執(zhí)行結(jié)果。

二、Stream 接口一覽

List 轉(zhuǎn) Stream

// 轉(zhuǎn)stream
list.stream()
// 并發(fā)處理
list.parallelStream()

filter(過濾)

Stream<T> filter(Predicate<? super T> predicate);

map(元素轉(zhuǎn)換)

<R> Stream<R> map(Function<? super T, ? extends R> mapper);
IntStream mapToInt(ToIntFunction<? super T> mapper);
LongStream mapToLong(ToLongFunction<? super T> mapper);
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);

flatMap(元素轉(zhuǎn)換)

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);

distinct(去除重復(fù),對象需要重寫 equals、hashCode)

Stream<T> distinct();

sorted(排序)

Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);

peek(生成新的流:流是單向的,例如用于日志打?。?/p>

Stream<T> peek(Consumer<? super T> action);

limit(取前面 n 個元素)

Stream<T> limit(long maxSize);

skip(跳過 n 個元素)

Stream<T> skip(long n);

forEach(遍歷)

void forEach(Consumer<? super T> action);
void forEachOrdered(Consumer<? super T> action);

toArray(轉(zhuǎn)換成數(shù)組)

Object[] toArray();
<A> A[] toArray(IntFunction<A[]> generator);

reduce(結(jié)果歸并)

T reduce(T identity, BinaryOperator<T> accumulator);
Optional<T> reduce(BinaryOperator<T> accumulator);
<U> U reduce(U identity,
            BiFunction<U, ? super T, U> accumulator,
            BinaryOperator<U> combiner);

collect(轉(zhuǎn)換成集合)

<R> R collect(Supplier<R> supplier,
             BiConsumer<R, ? super T> accumulator,
             BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);

轉(zhuǎn)list

// 轉(zhuǎn)list
Collectors.toList();
// 轉(zhuǎn)set
Collectors.toSet();
// 轉(zhuǎn)map
List<TestVo> testList = new ArrayList<>(10);
Map<Long, TestVo> data = releaseList.stream()
       .collect(Collectors.toMap(TestVo::getId, x -> x));

count(計數(shù))

long count();

查找

boolean anyMatch(Predicate<? super T> predicate);
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);

查找2

Optional<T> findFirst();
Optional<T> findAny();

三、Stream API 使用流

創(chuàng)建流

在使用流之前,首先需要擁有一個數(shù)據(jù)源,并通過StreamAPI提供的一些方法獲取該數(shù)據(jù)源的流對象。數(shù)據(jù)源可以有多種形式:

1. 集合

這種數(shù)據(jù)源較為常用,通過stream()方法即可獲取流對象:

List<Person> list = new ArrayList<Person>(); 
Stream<Person> stream = list.stream();

2. 數(shù)組

通過Arrays類提供的靜態(tài)函數(shù)stream()獲取數(shù)組的流對象:

String[] names = {"chaimm","peter","john"};
Stream<String> stream = Arrays.stream(names);

3. 值

直接將幾個值變成流對象:

Stream<String> stream = Stream.of("chaimm","peter","john");

4. 文件

try(Stream lines = Files.lines(Paths.get(“文件路徑名”),Charset.defaultCharset())){
    //可對lines做一些操作
}catch(IOException e){
}

5. iterator

創(chuàng)建無限流

Stream.iterate(0, n -> n + 2)
      .limit(10)
      .forEach(System.out::println);

PS:Java7簡化了IO操作,把打開IO操作放在try后的括號中即可省略關(guān)閉IO的代碼。

篩選 filter

filter 函數(shù)接收一個Lambda表達(dá)式作為參數(shù),該表達(dá)式返回boolean,在執(zhí)行過程中,流將元素逐一輸送給filter,并篩選出執(zhí)行結(jié)果為true的元素。 如,篩選出所有學(xué)生:

List<Person> result = list.stream()
                    .filter(Person::isStudent)
                    .collect(toList());

去重distinct

去掉重復(fù)的結(jié)果:

List<Person> result = list.stream()
                    .distinct()
                    .collect(toList());

截取

截取流的前N個元素:

List<Person> result = list.stream()
                    .limit(3)
                    .collect(toList());

跳過

跳過流的前n個元素:

List<Person> result = list.stream()
                    .skip(3)
                    .collect(toList());

映射

對流中的每個元素執(zhí)行一個函數(shù),使得元素轉(zhuǎn)換成另一種類型輸出。

流會將每一個元素輸送給map函數(shù),并執(zhí)行map中的Lambda表達(dá)式,最后將執(zhí)行結(jié)果存入一個新的流中。

如,獲取每個人的姓名(實則是將Perosn類型轉(zhuǎn)換成String類型):

List<Person> result = list.stream()
                    .map(Person::getName)
                    .collect(toList());

合并多個流

例:列出List中各不相同的單詞,List集合如下:

List<String> list = new ArrayList<String>();
list.add("I am a boy");
list.add("I love the girl");
list.add("But the girl loves another girl");

思路如下:

首先將list變成流:

list.stream();

按空格分詞:

list.stream()
            .map(line->line.split(" "));

分完詞之后,每個元素變成了一個String[]數(shù)組。

將每個 String[] 變成流:

list.stream()
            .map(line->line.split(" "))
            .map(Arrays::stream)

此時一個大流里面包含了一個個小流,我們需要將這些小流合并成一個流。

將小流合并成一個大流:用 flatMap 替換剛才的 map

list.stream()
    .map(line->line.split(" "))
    .flatMap(Arrays::stream)

去重

list.stream()
    .map(line->line.split(" "))
    .flatMap(Arrays::stream)
    .distinct()
    .collect(toList());

是否匹配任一元素:anyMatch

anyMatch用于判斷流中是否存在至少一個元素滿足指定的條件,這個判斷條件通過Lambda表達(dá)式傳遞給anyMatch,執(zhí)行結(jié)果為boolean類型。

如,判斷l(xiāng)ist中是否有學(xué)生:

boolean result = list.stream()
            .anyMatch(Person::isStudent);

是否匹配所有元素:allMatch

allMatch用于判斷流中的所有元素是否都滿足指定條件,這個判斷條件通過Lambda表達(dá)式傳遞給anyMatch,執(zhí)行結(jié)果為boolean類型。

如,判斷是否所有人都是學(xué)生:

boolean result = list.stream()
            .allMatch(Person::isStudent);

是否未匹配所有元素:noneMatch

noneMatch與allMatch恰恰相反,它用于判斷流中的所有元素是否都不滿足指定條件:

boolean result = list.stream()
            .noneMatch(Person::isStudent);

獲取任一元素findAny

findAny能夠從流中隨便選一個元素出來,它返回一個Optional類型的元素。

Optional<Person> person = list.stream().findAny();

獲取第一個元素findFirst

Optional<Person> person = list.stream().findFirst();

歸約

歸約是將集合中的所有元素經(jīng)過指定運算,折疊成一個元素輸出,如:求最值、平均數(shù)等,這些操作都是將一個集合的元素折疊成一個元素輸出。

在流中,reduce函數(shù)能實現(xiàn)歸約。 reduce函數(shù)接收兩個參數(shù):

  • 初始值
  • 進(jìn)行歸約操作的Lambda表達(dá)式

元素求和:自定義Lambda表達(dá)式實現(xiàn)求和

例:計算所有人的年齡總和

@Test
public void contextLoads() {
   List<Person> list = new ArrayList<>();
   list.add(new Person().setAge(20));
   list.add(new Person().setAge(25));
   int age = list.stream().map(Person::getAge).reduce(0, Integer::sum);
   System.out.println(age);
}
@Data
@Accessors(chain = true)
class Person {
   private int age;
}
  • reduce的第一個參數(shù)表示初試值為0;
  • reduce的第二個參數(shù)為需要進(jìn)行的歸約操作,它接收一個擁有兩個參數(shù)的Lambda表達(dá)式,reduce會把流中的元素兩兩輸給Lambda表達(dá)式,最后將計算出累加之和。

元素求和:使用Integer.sum函數(shù)求和

上面的方法中我們自己定義了Lambda表達(dá)式實現(xiàn)求和運算,如果當(dāng)前流的元素為數(shù)值類型,那么可以使用Integer提供了sum函數(shù)代替自定義的Lambda表達(dá)式,如:

int age = list.stream().reduce(0, Integer::sum);

Integer類還提供了 min 、 max 等一系列數(shù)值操作,當(dāng)流中元素為數(shù)值類型時可以直接使用。

數(shù)值流的使用

采用reduce進(jìn)行數(shù)值操作會涉及到基本數(shù)值類型和引用數(shù)值類型之間的裝箱、拆箱操作,因此效率較低。 當(dāng)流操作為純數(shù)值操作時,使用數(shù)值流能獲得較高的效率。

將普通流轉(zhuǎn)換成數(shù)值流

StreamAPI提供了三種數(shù)值流:IntStream、DoubleStream、LongStream,也提供了將普通流轉(zhuǎn)換成數(shù)值流的三種方法:mapToInt、mapToDouble、mapToLong。 如,將Person中的age轉(zhuǎn)換成數(shù)值流:

IntStream stream = list.stream().mapToInt(Person::getAge);

數(shù)值計算

每種數(shù)值流都提供了數(shù)值計算函數(shù),如max、min、sum等。如,找出最大的年齡:

OptionalInt maxAge = list.stream()
                                .mapToInt(Person::getAge)
                                .max();

由于數(shù)值流可能為空,并且給空的數(shù)值流計算最大值是沒有意義的,因此max函數(shù)返回OptionalInt,它是Optional的一個子類,能夠判斷流是否為空,并對流為空的情況作相應(yīng)的處理。 此外,mapToInt、mapToDouble、mapToLong進(jìn)行數(shù)值操作后的返回結(jié)果分別為:OptionalInt、OptionalDouble、OptionalLong

中間操作和收集操作

操作類型返回類型使用的類型/函數(shù)式接口函數(shù)描述符
filter中間Stream<T>Predicate<T>T -> boolean
distinct中間Stream<T>
skip中間Stream<T>long
map中間Stream<R>Function<T, R>T -> R
flatMap中間Stream<R>Function<T, Stream<R>>T -> Stream<R>
limit中間Stream<T>long
sorted中間Stream<T>Comparator<T>(T, T) -> int
anyMatch終端booleanPredicate<T>T -> boolean
noneMatch終端booleanPredicate<T>T -> boolean
allMatch終端booleanPredicate<T>T -> boolean
findAny終端Optional<T>
findFirst終端Optional<T>
forEach終端voidConsumer<T>T -> void
collect終端RCollector<T, A, R>
reduce終端Optional<T>BinaryOperator<T>(T, T) -> T
count終端long

四、Stream API

Collector 收集

收集器用來將經(jīng)過篩選、映射的流進(jìn)行最后的整理,可以使得最后的結(jié)果以不同的形式展現(xiàn)。

collect 方法即為收集器,它接收 Collector 接口的實現(xiàn)作為具體收集器的收集方法。

Collector 接口提供了很多默認(rèn)實現(xiàn)的方法,我們可以直接使用它們格式化流的結(jié)果;也可以自定義 Collector 接口的實現(xiàn),從而定制自己的收集器。

歸約

流由一個個元素組成,歸約就是將一個個元素“折疊”成一個值,如求和、求最值、求平均值都是歸約操作。

一般性歸約

若你需要自定義一個歸約操作,那么需要使用 Collectors.reducing 函數(shù),該函數(shù)接收三個參數(shù):

  • 第一個參數(shù)為歸約的初始值
  • 第二個參數(shù)為歸約操作進(jìn)行的字段
  • 第三個參數(shù)為歸約操作的過程

匯總

Collectors類專門為匯總提供了一個工廠方法: Collectors.summingInt 。

它可接受一 個把對象映射為求和所需int的函數(shù),并返回一個收集器;該收集器在傳遞給普通的 collect 方法后即執(zhí)行我們需要的匯總操作。

分組

數(shù)據(jù)分組是一種更自然的分割數(shù)據(jù)操作,分組就是將流中的元素按照指定類別進(jìn)行劃分,類似于SQL語句中的 GROUPBY 。

多級分組

多級分組可以支持在完成一次分組后,分別對每個小組再進(jìn)行分組。 使用具有兩個參數(shù)的 groupingBy 重載方法即可實現(xiàn)多級分組。

  • 第一個參數(shù):一級分組的條件
  • 第二個參數(shù):一個新的 groupingBy 函數(shù),該函數(shù)包含二級分組的條件

Collectors 類的靜態(tài)工廠方法

工廠方法返回類型用途示例
toListList<T>把流中所有項目收集到一個 ListList<Project> projects = projectStream.collect(toList());
toSetSet<T>把流中所有項目收集到一個 Set,刪除重復(fù)項Set<Project> projects = projectStream.collect(toSet());
toCollectionCollection<T>把流中所有項目收集到給定的供應(yīng)源創(chuàng)建的集合Collection<Project> projects = projectStream.collect(toCollection(), ArrayList::new);
countingLong計算流中元素的個數(shù)long howManyProjects = projectStream.collect(counting());
summingIntInteger對流中項目的一個整數(shù)屬性求和int totalStars = projectStream.collect(summingInt(Project::getStars));
averagingIntDouble計算流中項目 Integer 屬性的平均值double avgStars = projectStream.collect(averagingInt(Project::getStars));
summarizingIntIntSummaryStatistics收集關(guān)于流中項目 Integer 屬性的統(tǒng)計值,例如最大、最小、 總和與平均值IntSummaryStatistics projectStatistics = projectStream.collect(summarizingInt(Project::getStars));
joiningString連接對流中每個項目調(diào)用 toString 方法所生成的字符串String shortProject = projectStream.map(Project::getName).collect(joining(", "));
maxByOptional<T>按照給定比較器選出的最大元素的 Optional, 或如果流為空則為 Optional.empty()Optional<Project> fattest = projectStream.collect(maxBy(comparingInt(Project::getStars)));
minByOptional<T>按照給定比較器選出的最小元素的 Optional, 或如果流為空則為 Optional.empty()Optional<Project> fattest = projectStream.collect(minBy(comparingInt(Project::getStars)));
reducing歸約操作產(chǎn)生的類型從一個作為累加器的初始值開始,利用 BinaryOperator 與流中的元素逐個結(jié)合,從而將流歸約為單個值int totalStars = projectStream.collect(reducing(0, Project::getStars, Integer::sum));
collectingAndThen轉(zhuǎn)換函數(shù)返回的類型包含另一個收集器,對其結(jié)果應(yīng)用轉(zhuǎn)換函數(shù)int howManyProjects = projectStream.collect(collectingAndThen(toList(), List::size));
groupingByMap<K, List<T>>根據(jù)項目的一個屬性的值對流中的項目作問組,并將屬性值作 為結(jié)果 Map 的鍵Map<String,List<Project>> projectByLanguage = projectStream.collect(groupingBy(Project::getLanguage));
partitioningByMap<Boolean,List<T>>根據(jù)對流中每個項目應(yīng)用斷言的結(jié)果來對項目進(jìn)行分區(qū)Map<Boolean,List<Project>> vegetarianDishes = projectStream.collect(partitioningBy(Project::isVegetarian));

轉(zhuǎn)換類型

有一些收集器可以生成其他集合。比如前面已經(jīng)見過的 toList ,生成了 java.util.List 類的實例。 還有 toSet 和 toCollection ,分別生成 Set 和 Collection 類的實例。 到目前為止, 我已經(jīng)講了很多流上的鏈?zhǔn)讲僮?,但總有一些時候,需要最終生成一個集合——比如:

  • 已有代碼是為集合編寫的,因此需要將流轉(zhuǎn)換成集合傳入;
  • 在集合上進(jìn)行一系列鏈?zhǔn)讲僮骱?,最終希望生成一個值;
  • 寫單元測試時,需要對某個具體的集合做斷言。

使用 toCollection ,用定制的集合收集元素

stream.collect(toCollection(TreeSet::new));

還可以利用收集器讓流生成一個值。 maxBy 和 minBy 允許用戶按某種特定的順序生成一個值。

數(shù)據(jù)分區(qū)

分區(qū)是分組的特殊情況:由一個斷言(返回一個布爾值的函數(shù))作為分類函數(shù),它稱分區(qū)函數(shù)。 分區(qū)函數(shù)返回一個布爾值,這意味著得到的分組 Map 的鍵類型是 Boolean,于是它最多可以分為兩組: true是一組,false是一組。

分區(qū)的好處在于保留了分區(qū)函數(shù)返回true或false的兩套流元素列表。

并行流

并行流就是一個把內(nèi)容分成多個數(shù)據(jù)塊,并用不不同的線程分別處理每個數(shù)據(jù)塊的流。最后合并每個數(shù)據(jù)塊的計算結(jié)果。

將一個順序執(zhí)行的流轉(zhuǎn)變成一個并發(fā)的流只要調(diào)用 parallel() 方法

public static long parallelSum(long n){
    return Stream.iterate(1L, i -> i +1).limit(n).parallel().reduce(0L,Long::sum);
}

將一個并發(fā)流轉(zhuǎn)成順序的流只要調(diào)用 sequential() 方法

stream.parallel().filter(...).sequential().map(...).parallel().reduce();

這兩個方法可以多次調(diào)用,只有最后一個調(diào)用決定這個流是順序的還是并發(fā)的。

并發(fā)流使用的默認(rèn)線程數(shù)等于你機(jī)器的處理器核心數(shù)。

通過這個方法可以修改這個值,這是全局屬性。

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "12");

并非使用多線程并行流處理數(shù)據(jù)的性能一定高于單線程順序流的性能,因為性能受到多種因素的影響。

如何高效使用并發(fā)流的一些建議:

  1. 如果不確定, 就自己測試。
  2. 盡量使用基本類型的流 IntStream, LongStream, DoubleStream
  3. 有些操作使用并發(fā)流的性能會比順序流的性能更差,比如limit,findFirst,依賴元素順序的操作在并發(fā)流中是極其消耗性能的。findAny的性能就會好很多,應(yīng)為不依賴順序。
  4. 考慮流中計算的性能(Q)和操作的性能(N)的對比, Q表示單個處理所需的時間,N表示需要處理的數(shù)量,如果Q的值越大, 使用并發(fā)流的性能就會越高。
  5. 數(shù)據(jù)量不大時使用并發(fā)流,性能得不到提升。
  6. 考慮數(shù)據(jù)結(jié)構(gòu):并發(fā)流需要對數(shù)據(jù)進(jìn)行分解,不同的數(shù)據(jù)結(jié)構(gòu)被分解的性能時不一樣的。

流的數(shù)據(jù)源和可分解性

可分解性
ArrayList非常好
LinkedList
IntStream.range非常好
Stream.iterate
HashSet
TreeSet

流的特性以及中間操作對流的修改都會對數(shù)據(jù)對分解性能造成影響。

比如固定大小的流在任務(wù)分解的時候就可以平均分配,但是如果有filter操作,那么流就不能預(yù)先知道在這個操作后還會剩余多少元素。

考慮終端操作的性能:如果終端操作在合并并發(fā)流的計算結(jié)果時的性能消耗太大,那么使用并發(fā)流提升的性能就會得不償失。

到此這篇關(guān)于Java8新特性之Stream使用詳解的文章就介紹到這了,更多相關(guān)Java8的Stream內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺析Java中對稱與非對稱加密算法原理與使用

    淺析Java中對稱與非對稱加密算法原理與使用

    密碼學(xué)是研究編制密碼和破譯密碼的技術(shù)科學(xué)。這篇文章主要為大家介紹了Java中對稱與非對稱加密算法的原理與使用,感興趣的小伙伴可以了解一下
    2023-03-03
  • Java spring webmvc如何實現(xiàn)控制反轉(zhuǎn)

    Java spring webmvc如何實現(xiàn)控制反轉(zhuǎn)

    這篇文章主要介紹了Java spring webmvc如何實現(xiàn)控制反轉(zhuǎn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • Spring Boot 3.x 集成 Eureka Server/Client的詳細(xì)過程

    Spring Boot 3.x 集成 Eureka Server/Cl

    隨著SpringBoot 3.x版本的開發(fā)嘗試,本文記錄了在集成Eureka Server/Client時所遇到的問題和解決方案,文中詳細(xì)介紹了搭建服務(wù)、配置文件和測試步驟,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • java與scala數(shù)組及集合的基本操作對比

    java與scala數(shù)組及集合的基本操作對比

    這篇文章主要介紹了java與scala數(shù)組及集合的基本操作對比,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java通過jedis連接redis的幾種常用方法

    Java通過jedis連接redis的幾種常用方法

    jedis封裝了redis原有的操作命令,使用起來很簡單,本文主要介紹了Java通過jedis連接redis的幾種常用方法,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Java 繼承與多態(tài)超詳細(xì)梳理

    Java 繼承與多態(tài)超詳細(xì)梳理

    繼承就是可以直接使用前輩的屬性和方法。自然界如果沒有繼承,那一切都是處于混沌狀態(tài)。多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作
    2022-04-04
  • JFormDesigner(IDEA)下載方法

    JFormDesigner(IDEA)下載方法

    JFormDesigner是一種Java Swing GUI設(shè)計工具,可快速創(chuàng)建用戶界面,支持多種布局管理器,如GridBagLayout、SpringLayout等,本文給大家介紹JFormDesigner(IDEA)下載方法,感興趣的朋友跟隨小編一起看看吧
    2023-12-12
  • springboot?無法自動裝配的問題

    springboot?無法自動裝配的問題

    這篇文章主要介紹了springboot?無法自動裝配的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 詳解MyBatis多數(shù)據(jù)源配置(讀寫分離)

    詳解MyBatis多數(shù)據(jù)源配置(讀寫分離)

    這篇文章主要介紹了詳解MyBatis多數(shù)據(jù)源配置(讀寫分離),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Spring Boot接收單個String入?yún)⒌慕鉀Q方法

    Spring Boot接收單個String入?yún)⒌慕鉀Q方法

    這篇文章主要給大家介紹了關(guān)于Spring Boot接收單個String入?yún)⒌慕鉀Q方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11

最新評論