最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java8新特性:函數(shù)式編程

 更新時間:2021年06月21日 17:31:15   作者:icarusliu81  
Java8最新引入函數(shù)式編程概念,該項技術(shù)可以大大提升編碼效率,本文會對涉及的對象等進(jìn)行兩種方法的對比,對新技術(shù)更直白的看到變化,更方便學(xué)習(xí)

首先需要清楚一個概念:函數(shù)式接口;它指的是有且只有一個未實現(xiàn)的方法的接口,一般通過FunctionalInterface這個注解來表明某個接口是一個函數(shù)式接口。函數(shù)式接口是Java支持函數(shù)式編程的基礎(chǔ)。

1 Java8函數(shù)式編程語法入門

Java8中函數(shù)式編程語法能夠精簡代碼。
使用Consumer作為示例,它是一個函數(shù)式接口,包含一個抽象方法accept,這個方法只有輸入而無輸出。
現(xiàn)在我們要定義一個Consumer對象,傳統(tǒng)的方式是這樣定義的:

Consumer c = new Consumer() {
    @Override
    public void accept(Object o) {
        System.out.println(o);
    }
};

而在Java8中,針對函數(shù)式編程接口,可以這樣定義:

Consumer c = (o) -> {
    System.out.println(o);
}; 

上面已說明,函數(shù)式編程接口都只有一個抽象方法,因此在采用這種寫法時,編譯器會將這段函數(shù)編譯后當(dāng)作該抽象方法的實現(xiàn)。
如果接口有多個抽象方法,編譯器就不知道這段函數(shù)應(yīng)該是實現(xiàn)哪個方法的了。
因此,=后面的函數(shù)體我們就可以看成是accept函數(shù)的實現(xiàn)。

  • 輸入:->前面的部分,即被()包圍的部分。此處只有一個輸入?yún)?shù),實際上輸入是可以有多個的,如兩個參數(shù)時寫法:(a, b);當(dāng)然也可以沒有輸入,此時直接就可以是()。
  • 函數(shù)體:->后面的部分,即被{}包圍的部分;可以是一段代碼。
  • 輸出:函數(shù)式編程可以沒有返回值,也可以有返回值。如果有返回值時,需要代碼段的最后一句通過return的方式返回對應(yīng)的值。

當(dāng)函數(shù)體中只有一個語句時,可以去掉{}進(jìn)一步簡化:

Consumer c = (o) -> System.out.println(o);

然而這還不是最簡的,由于此處只是進(jìn)行打印,調(diào)用了System.out中的println靜態(tài)方法對輸入?yún)?shù)直接進(jìn)行打印,因此可以簡化成以下寫法:

Consumer c = System.out::println;

它表示的意思就是針對輸入的參數(shù)將其調(diào)用System.out中的靜態(tài)方法println進(jìn)行打印。
到這一步就可以感受到函數(shù)式編程的強(qiáng)大能力。
通過最后一段代碼,我們可以簡單的理解函數(shù)式編程,Consumer接口直接就可以當(dāng)成一個函數(shù)了,這個函數(shù)接收一個輸入?yún)?shù),然后針對這個輸入進(jìn)行處理;當(dāng)然其本質(zhì)上仍舊是一個對象,但我們已經(jīng)省去了諸如老方式中的對象定義過程,直接使用一段代碼來給函數(shù)式接口對象賦值。
而且最為關(guān)鍵的是,這個函數(shù)式對象因為本質(zhì)上仍舊是一個對象,因此可以做為其它方法的參數(shù)或者返回值,可以與原有的代碼實現(xiàn)無縫集成!

下面對Java中的幾個預(yù)先定義的函數(shù)式接口及其經(jīng)常使用的類進(jìn)行分析學(xué)習(xí)。

2 Java函數(shù)式接口

2.1 Consumer

Consumer是一個函數(shù)式編程接口; 顧名思義,Consumer的意思就是消費,即針對某個東西我們來使用它,因此它包含有一個有輸入而無輸出的accept接口方法;
除accept方法,它還包含有andThen這個方法;
其定義如下:

default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (T t) -> { accept(t); after.accept(t); };
}

可見這個方法就是指定在調(diào)用當(dāng)前Consumer后是否還要調(diào)用其它的Consumer;
使用示例:

public static void consumerTest() {
    Consumer f = System.out::println;
    Consumer f2 = n -> System.out.println(n + "-F2");

    //執(zhí)行完F后再執(zhí)行F2的Accept方法
    f.andThen(f2).accept("test");

    //連續(xù)執(zhí)行F的Accept方法
    f.andThen(f).andThen(f).andThen(f).accept("test1");
}

2.2 Function

Function也是一個函數(shù)式編程接口;它代表的含義是“函數(shù)”,而函數(shù)經(jīng)常是有輸入輸出的,因此它含有一個apply方法,包含一個輸入與一個輸出;
除apply方法外,它還有compose與andThen及indentity三個方法,其使用見下述示例;

/**
 * Function測試
 */
public static void functionTest() {
    Function<Integer, Integer> f = s -> s++;
    Function<Integer, Integer> g = s -> s * 2;

    /**
     * 下面表示在執(zhí)行F時,先執(zhí)行G,并且執(zhí)行F時使用G的輸出當(dāng)作輸入。
     * 相當(dāng)于以下代碼:
     * Integer a = g.apply(1);
     * System.out.println(f.apply(a));
     */
    System.out.println(f.compose(g).apply(1));

    /**
     * 表示執(zhí)行F的Apply后使用其返回的值當(dāng)作輸入再執(zhí)行G的Apply;
     * 相當(dāng)于以下代碼
     * Integer a = f.apply(1);
     * System.out.println(g.apply(a));
     */
    System.out.println(f.andThen(g).apply(1));

    /**
     * identity方法會返回一個不進(jìn)行任何處理的Function,即輸出與輸入值相等; 
     */
    System.out.println(Function.identity().apply("a"));
}

2.3 Predicate

Predicate為函數(shù)式接口,predicate的中文意思是“斷定”,即判斷的意思,判斷某個東西是否滿足某種條件; 因此它包含test方法,根據(jù)輸入值來做邏輯判斷,其結(jié)果為True或者False。
它的使用方法示例如下:

/**
 * Predicate測試
 */
private static void predicateTest() {
    Predicate<String> p = o -> o.equals("test");
    Predicate<String> g = o -> o.startsWith("t");

    /**
     * negate: 用于對原來的Predicate做取反處理;
     * 如當(dāng)調(diào)用p.test("test")為True時,調(diào)用p.negate().test("test")就會是False;
     */
    Assert.assertFalse(p.negate().test("test"));

    /**
     * and: 針對同一輸入值,多個Predicate均返回True時返回True,否則返回False;
     */
    Assert.assertTrue(p.and(g).test("test"));

    /**
     * or: 針對同一輸入值,多個Predicate只要有一個返回True則返回True,否則返回False
     */
    Assert.assertTrue(p.or(g).test("ta"));
}

3 函數(shù)式編程接口的使用

通過Stream以及Optional兩個類,可以進(jìn)一步利用函數(shù)式接口來簡化代碼。

3.1 Stream

Stream可以對多個元素進(jìn)行一系列的操作,也可以支持對某些操作進(jìn)行并發(fā)處理。

3.1.1 Stream對象的創(chuàng)建

Stream對象的創(chuàng)建途徑有以下幾種

a. 創(chuàng)建空的Stream對象

Stream stream = Stream.empty();

b. 通過集合類中的stream或者parallelStream方法創(chuàng)建;

List<String> list = Arrays.asList("a", "b", "c", "d");
Stream listStream = list.stream();                   //獲取串行的Stream對象
Stream parallelListStream = list.parallelStream();   //獲取并行的Stream對象

c. 通過Stream中的of方法創(chuàng)建:

Stream s = Stream.of("test");
Stream s1 = Stream.of("a", "b", "c", "d");

d. 通過Stream中的iterate方法創(chuàng)建:
iterate方法有兩個不同參數(shù)的方法:

public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f);  
public static<T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)

其中第一個方法將會返回一個無限有序值的Stream對象:它的第一個元素是seed,第二個元素是f.apply(seed); 第N個元素是f.apply(n-1個元素的值);生成無限值的方法實際上與Stream的中間方法類似,在遇到中止方法前一般是不真正的執(zhí)行的。因此無限值的這個方法一般與limit等方法一起使用,來獲取前多少個元素。
當(dāng)然獲取前多少個元素也可以使用第二個方法。
第二個方法與第一個方法生成元素的方式類似,不同的是它返回的是一個有限值的Stream;中止條件是由hasNext來斷定的。

第二種方法的使用示例如下:

/**
 * 本示例表示從1開始組裝一個序列,第一個是1,第二個是1+1即2,第三個是2+1即3..,直接10時中止;
 * 也可簡化成以下形式:
 *        Stream.iterate(1,
 *        n -> n <= 10,
 *        n -> n+1).forEach(System.out::println);
 * 寫成以下方式是為簡化理解
 */
Stream.iterate(1,
        new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer <= 10;
            }
        },
    new UnaryOperator<Integer>() {
        @Override
        public Integer apply(Integer integer) {
            return integer+1;
        }
}).forEach(System.out::println);

e. 通過Stream中的generate方法創(chuàng)建
與iterate中創(chuàng)建無限元素的Stream類似,不過它的每個元素與前一元素?zé)o關(guān),且生成的是一個無序的隊列。也就是說每一個元素都可以隨機(jī)生成。因此一般用來創(chuàng)建常量的Stream以及隨機(jī)的Stream等。
示例如下:

/**
 * 隨機(jī)生成10個Double元素的Stream并將其打印
 */
Stream.generate(new Supplier<Double>() {
    @Override
    public Double get() {
        return Math.random();
    }
}).limit(10).forEach(System.out::println);

//上述寫法可以簡化成以下寫法:
Stream.generate(() -> Math.random()).limit(10).forEach(System.out::println);

f. 通過Stream中的concat方法連接兩個Stream對象生成新的Stream對象 這個比較好理解不再贅述。

3.1.2 Stream對象的使用

Stream對象提供多個非常有用的方法,這些方法可以分成兩類:
中間操作:將原始的Stream轉(zhuǎn)換成另外一個Stream;如filter返回的是過濾后的Stream。
終端操作:產(chǎn)生的是一個結(jié)果或者其它的復(fù)合操作;如count或者forEach操作。

其清單如下所示,方法的具體說明及使用示例見后文。
所有中間操作

方法 說明
sequential 返回一個相等的串行的Stream對象,如果原Stream對象已經(jīng)是串行就可能會返回原對象
parallel 返回一個相等的并行的Stream對象,如果原Stream對象已經(jīng)是并行的就會返回原對象
unordered 返回一個不關(guān)心順序的Stream對象,如果原對象已經(jīng)是這類型的對象就會返回原對象
onClose 返回一個相等的Steam對象,同時新的Stream對象在執(zhí)行Close方法時會調(diào)用傳入的Runnable對象
close 關(guān)閉Stream對象
filter 元素過濾:對Stream對象按指定的Predicate進(jìn)行過濾,返回的Stream對象中僅包含未被過濾的元素
map 元素一對一轉(zhuǎn)換:使用傳入的Function對象對Stream中的所有元素進(jìn)行處理,返回的Stream對象中的元素為原元素處理后的結(jié)果
mapToInt 元素一對一轉(zhuǎn)換:將原Stream中的使用傳入的IntFunction加工后返回一個IntStream對象
flatMap 元素一對多轉(zhuǎn)換:對原Stream中的所有元素進(jìn)行操作,每個元素會有一個或者多個結(jié)果,然后將返回的所有元素組合成一個統(tǒng)一的Stream并返回;
distinct 去重:返回一個去重后的Stream對象
sorted 排序:返回排序后的Stream對象
peek 使用傳入的Consumer對象對所有元素進(jìn)行消費后,返回一個新的包含所有原來元素的Stream對象
limit 獲取有限個元素組成新的Stream對象返回
skip 拋棄前指定個元素后使用剩下的元素組成新的Stream返回
takeWhile 如果Stream是有序的(Ordered),那么返回最長命中序列(符合傳入的Predicate的最長命中序列)組成的Stream;如果是無序的,那么返回的是所有符合傳入的Predicate的元素序列組成的Stream。
dropWhile 與takeWhile相反,如果是有序的,返回除最長命中序列外的所有元素組成的Stream;如果是無序的,返回所有未命中的元素組成的Stream。

所有終端操作

方法 說明
iterator 返回Stream中所有對象的迭代器;
spliterator 返回對所有對象進(jìn)行的spliterator對象
forEach 對所有元素進(jìn)行迭代處理,無返回值
forEachOrdered 按Stream的Encounter所決定的序列進(jìn)行迭代處理,無返回值
toArray 返回所有元素的數(shù)組
reduce 使用一個初始化的值,與Stream中的元素一一做傳入的二合運算后返回最終的值。每與一個元素做運算后的結(jié)果,再與下一個元素做運算。它不保證會按序列執(zhí)行整個過程。
collect 根據(jù)傳入?yún)?shù)做相關(guān)匯聚計算
min 返回所有元素中最小值的Optional對象;如果Stream中無任何元素,那么返回的Optional對象為Empty
max 與Min相反
count 所有元素個數(shù)
anyMatch 只要其中有一個元素滿足傳入的Predicate時返回True,否則返回False
allMatch 所有元素均滿足傳入的Predicate時返回True,否則False
noneMatch 所有元素均不滿足傳入的Predicate時返回True,否則False
findFirst 返回第一個元素的Optioanl對象;如果無元素返回的是空的Optional; 如果Stream是無序的,那么任何元素都可能被返回。
findAny 返回任意一個元素的Optional對象,如果無元素返回的是空的Optioanl。
isParallel 判斷是否當(dāng)前Stream對象是并行的

下面就幾個比較常用的方法舉例說明其用法:

3.1.2.1 filter

用于對Stream中的元素進(jìn)行過濾,返回一個過濾后的Stream
其方法定義如下:

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

使用示例:

Stream<String> s = Stream.of("test", "t1", "t2", "teeeee", "aaaa");
//查找所有包含t的元素并進(jìn)行打印
s.filter(n -> n.contains("t")).forEach(System.out::println);

3.1.2.2 map

元素一對一轉(zhuǎn)換。
它接收一個Funcation參數(shù),用其對Stream中的所有元素進(jìn)行處理,返回的Stream對象中的元素為Function對原元素處理后的結(jié)果
其方法定義如下:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

示例,假設(shè)我們要將一個String類型的Stream對象中的每個元素添加相同的后綴.txt,如a變成a.txt,其寫法如下:

Stream<String> s = Stream.of("test", "t1", "t2", "teeeee", "aaaa");
s.map(n -> n.concat(".txt")).forEach(System.out::println);

3.1.2.3 flatMap

元素一對多轉(zhuǎn)換:對原Stream中的所有元素使用傳入的Function進(jìn)行處理,每個元素經(jīng)過處理后生成一個多個元素的Stream對象,然后將返回的所有Stream對象中的所有元素組合成一個統(tǒng)一的Stream并返回;
方法定義如下:

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

示例,假設(shè)要對一個String類型的Stream進(jìn)行處理,將每一個元素的拆分成單個字母,并打?。?/p>

Stream<String> s = Stream.of("test", "t1", "t2", "teeeee", "aaaa");
s.flatMap(n -> Stream.of(n.split(""))).forEach(System.out::println);

3.1.2.4 takeWhile

方法定義如下:

default Stream<T> takeWhile(Predicate<? super T> predicate)

如果Stream是有序的(Ordered),那么返回最長命中序列(符合傳入的Predicate的最長命中序列)組成的Stream;如果是無序的,那么返回的是所有符合傳入的Predicate的元素序列組成的Stream。
與Filter有點類似,不同的地方就在當(dāng)Stream是有序時,返回的只是最長命中序列。
如以下示例,通過takeWhile查找”test”, “t1”, “t2”, “teeeee”, “aaaa”, “taaa”這幾個元素中包含t的最長命中序列:

Stream<String> s = Stream.of("test", "t1", "t2", "teeeee", "aaaa", "taaa");
//以下結(jié)果將打?。?"test", "t1", "t2", "teeeee",最后的那個taaa不會進(jìn)行打印 
s.takeWhile(n -> n.contains("t")).forEach(System.out::println);

3.1.2.5 dropWhile

與takeWhile相反,如果是有序的,返回除最長命中序列外的所有元素組成的Stream;如果是無序的,返回所有未命中的元素組成的Stream;其定義如下:

default Stream<T> dropWhile(Predicate<? super T> predicate)

如以下示例,通過dropWhile刪除”test”, “t1”, “t2”, “teeeee”, “aaaa”, “taaa”這幾個元素中包含t的最長命中序列:

Stream<String> s = Stream.of("test", "t1", "t2", "teeeee", "aaaa", "taaa");
//以下結(jié)果將打?。?aaaa", "taaa"  
s.dropWhile(n -> n.contains("t")).forEach(System.out::println);

3.1.2.6 reduce與collect

關(guān)于reduce與collect由于功能較為復(fù)雜,在后續(xù)將進(jìn)行單獨分析與學(xué)習(xí),此處暫不涉及。

3.2 Optional

用于簡化Java中對空值的判斷處理,以防止出現(xiàn)各種空指針異常。
Optional實際上是對一個變量進(jìn)行封裝,它包含有一個屬性value,實際上就是這個變量的值。

3.2.1 Optional對象創(chuàng)建

它的構(gòu)造函數(shù)都是private類型的,因此要初始化一個Optional的對象無法通過其構(gòu)造函數(shù)進(jìn)行創(chuàng)建。它提供了一系列的靜態(tài)方法用于構(gòu)建Optional對象:

3.2.1.1 empty

用于創(chuàng)建一個空的Optional對象;其value屬性為Null。
如:

Optional o = Optional.empty();

3.2.1.2 of

根據(jù)傳入的值構(gòu)建一個Optional對象;
傳入的值必須是非空值,否則如果傳入的值為空值,則會拋出空指針異常。
使用:

o = Optional.of("test"); 

3.2.1.3 ofNullable

根據(jù)傳入值構(gòu)建一個Optional對象
傳入的值可以是空值,如果傳入的值是空值,則與empty返回的結(jié)果是一樣的。

3.2.2 方法

Optional包含以下方法:

方法名 說明
get 獲取Value的值,如果Value值是空值,則會拋出NoSuchElementException異常;因此返回的Value值無需再做空值判斷,只要沒有拋出異常,都會是非空值。
isPresent Value是否為空值的判斷;
ifPresent 當(dāng)Value不為空時,執(zhí)行傳入的Consumer;
ifPresentOrElse Value不為空時,執(zhí)行傳入的Consumer;否則執(zhí)行傳入的Runnable對象;
filter 當(dāng)Value為空或者傳入的Predicate對象調(diào)用test(value)返回False時,返回Empty對象;否則返回當(dāng)前的Optional對象
map 一對一轉(zhuǎn)換:當(dāng)Value為空時返回Empty對象,否則返回傳入的Function執(zhí)行apply(value)后的結(jié)果組裝的Optional對象;
flatMap 一對多轉(zhuǎn)換:當(dāng)Value為空時返回Empty對象,否則傳入的Function執(zhí)行apply(value)后返回的結(jié)果(其返回結(jié)果直接是Optional對象)
or 如果Value不為空,則返回當(dāng)前的Optional對象;否則,返回傳入的Supplier生成的Optional對象;
stream 如果Value為空,返回Stream對象的Empty值;否則返回Stream.of(value)的Stream對象;
orElse Value不為空則返回Value,否則返回傳入的值;
orElseGet Value不為空則返回Value,否則返回傳入的Supplier生成的值;
orElseThrow Value不為空則返回Value,否則拋出Supplier中生成的異常對象;

3.2.3 使用場景

常用的使用場景如下:

3.2.3.1 判斷結(jié)果不為空后使用

如某個函數(shù)可能會返回空值,以往的做法:

String s = test();
if (null != s) {
    System.out.println(s);
}

現(xiàn)在的寫法就可以是:

Optional<String> s = Optional.ofNullable(test());
s.ifPresent(System.out::println);

乍一看代碼復(fù)雜度上差不多甚至是略有提升;那為什么要這么做呢?
一般情況下,我們在使用某一個函數(shù)返回值時,要做的第一步就是去分析這個函數(shù)是否會返回空值;如果沒有進(jìn)行分析或者分析的結(jié)果出現(xiàn)偏差,導(dǎo)致函數(shù)會拋出空值而沒有做檢測,那么就會相應(yīng)的拋出空指針異常!
而有了Optional后,在我們不確定時就可以不用去做這個檢測了,所有的檢測Optional對象都幫忙我們完成,我們要做的就是按上述方式去處理。

3.2.3.2 變量為空時提供默認(rèn)值

如要判斷某個變量為空時使用提供的值,然后再針對這個變量做某種運算;
以往做法:

if (null == s) {
    s = "test";
}
System.out.println(s);

現(xiàn)在的做法:

Optional<String> o = Optional.ofNullable(s);
System.out.println(o.orElse("test"));

3.2.3.3 變量為空時拋出異常,否則使用

以往寫法:

if (null == s) {
    throw new Exception("test");
}
System.out.println(s);

現(xiàn)在寫法:

Optional<String> o = Optional.ofNullable(s);
System.out.println(o.orElseThrow(()->new Exception("test")));

其它場景待補(bǔ)充。

總結(jié)

這邊文章是寫關(guān)于Java8新出的特性:函數(shù)式編程的內(nèi)容,包含Stream,Function,Optional,Consumer等內(nèi)容,更多相關(guān)Java8新特性的內(nèi)容請搜索腳本之家其他文章

相關(guān)文章

  • Java中classpath的基本概念和配置方法詳析

    Java中classpath的基本概念和配置方法詳析

    這篇文章主要介紹了Java中的classpath概念,包括其基本概念、設(shè)置方法以及在Java應(yīng)用中的作用,在IDE中的配置也進(jìn)行了詳細(xì)說明,并提到了一些通用注意事項,需要的朋友可以參考下
    2025-02-02
  • 詳解Spring Boot 定時任務(wù)的實現(xiàn)方法

    詳解Spring Boot 定時任務(wù)的實現(xiàn)方法

    最近在用SpringBoot寫一個關(guān)于定時項目的時候遇到一個問題,下面小編把如何處理定時任務(wù)的解決思路分享給大家 ,需要的朋友參考下
    2017-05-05
  • WeakHashMap的垃圾回收原理詳解

    WeakHashMap的垃圾回收原理詳解

    這篇文章主要介紹了WeakHashMap的垃圾回收原理詳解,WeakHashMap 與 HashMap 的用法基本類似,與 HashMap 的區(qū)別在于,HashMap的key保留了對實際對象的強(qiáng)引用個,這意味著只要該HashMap對象不被銷毀,該HashMap的所有key所引用的對象就不會被垃圾回收,需要的朋友可以參考下
    2023-09-09
  • Spring你不知道的一種解耦模式

    Spring你不知道的一種解耦模式

    本文介紹一種方法,服務(wù)定位模式Service?Locator?Pattern來解決,它幫助我們消除緊耦合實現(xiàn)及其依賴性,并提出將服務(wù)與其具體類解耦
    2023-01-01
  • 淺談Java中ArrayList線程不安全怎么辦

    淺談Java中ArrayList線程不安全怎么辦

    本文主要介紹了Java中ArrayList線程不安全怎么辦,主要有三種解決的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 關(guān)于HashMap 并發(fā)時會引起死循環(huán)的問題解析

    關(guān)于HashMap 并發(fā)時會引起死循環(huán)的問題解析

    JDK1.8之前采用頭插,即在鏈表結(jié)構(gòu)上每次都把數(shù)據(jù)放在鏈表頭部。JDK1.8采用尾插方法,很多朋友在學(xué)習(xí)Java并發(fā)容器和框架時,看到為什么要使用ConcurrentHashMap時不知道究其原因,今天小編通過本文給大家介紹下HashMap 并發(fā)死循環(huán)問題,一起看看吧
    2021-05-05
  • SpringBoot整合SpringSecurity實現(xiàn)JWT認(rèn)證的項目實踐

    SpringBoot整合SpringSecurity實現(xiàn)JWT認(rèn)證的項目實踐

    本文會通過創(chuàng)建SpringBoot項目整合SpringSecurity,實現(xiàn)完整的JWT認(rèn)證機(jī)制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java中IO流 字節(jié)流實例詳解

    Java中IO流 字節(jié)流實例詳解

    這篇文章主要介紹了Java中IO流 字節(jié)流實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • spring boot 的常用注解使用小結(jié)

    spring boot 的常用注解使用小結(jié)

    這篇文章主要介紹了spring boot 的常用注解使用小結(jié),需要的朋友可以參考下
    2017-05-05
  • 哈希表在算法題目中的實際應(yīng)用詳解(Java)

    哈希表在算法題目中的實際應(yīng)用詳解(Java)

    散列表(Hash?table,也叫哈希表)是根據(jù)關(guān)鍵碼值(Key?value)而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu),下面這篇文章主要給大家介紹了關(guān)于哈希表在算法題目中的實際應(yīng)用,文中介紹的方法是Java,需要的朋友可以參考下
    2024-03-03

最新評論

漳浦县| 荣成市| 金门县| 肇州县| 岚皋县| 杨浦区| 柳江县| 平和县| 丰都县| 类乌齐县| 太白县| 新巴尔虎左旗| 巫山县| 托里县| 买车| 锡林郭勒盟| 凤凰县| 岑巩县| 手机| 延庆县| 乡宁县| 砀山县| 金寨县| 长兴县| 孝义市| 顺昌县| 泰兴市| 商都县| 韩城市| 兴山县| 青田县| 西丰县| 藁城市| 威远县| 莱西市| 宝坻区| 泸州市| 潮州市| 郧西县| 金秀| 灵山县|