主頁 > 後端開發 > Java8 新特性

Java8 新特性

2020-09-23 00:45:12 後端開發

1、Java 8

2014 年 3 月 18 日,Oracle 發布了 Java 8,為目前唯二的 LTS(長期支持)版本之一,另一個是 Java 11,目前最新的版本為 Java 15

  • Java 8 為目前使用最多的發行版本

20200917223048

更多:Java版本歷史、Jetbrains Java編程

2、介面默認實作與靜態方法

Java 8 之后可以為介面方法提供一個默認實作,用 default 修飾符來標記方法,這樣就可以只關心需要的方法,而不用去實作不需要的方法

  • 在 JVM 中,介面的默認實作是非常高效的,并且通過位元組碼指令為方法呼叫提供了支持
interface Animal {
    // 默認實作
    default void cao() {
        System.out.println("animal 艸");
    }

    void ri();
}

class Human implements Animal {
    // 默認方法可以不進行重寫,非默認方法必須重寫
    @Override
    public void ri() {
        System.out.println("human 日");
    }
}

public class Test {
    public static void main(String[] args) {
        Human human = new Human();
        // 不需要重寫,直接呼叫默認方法
        human.cao();
        human.ri();
    }
}

2.1 默認方法沖突

如果在一個介面中定義了一個默認方法,又在超類或另一個介面中定義了同樣的方法,就會產生沖突

  • 超類優先:如果超類提供了一個具體方法,同名且有相同引數型別的默認方法會被忽略
  • 介面沖突:如果一個介面提供了一個默認方法,另一個介面提供了一個同名而且引數型別(不論是否是默認引數)相同的方法,必須覆寫這個方法來解決沖突
// 超類優先
interface Animal {
    default void cao() {
        System.out.println("animal 艸");
    }
}

class Mammal {
   public void cao() {
        System.out.println("mammal 艸");
    }
}

class Human extends Mammal implements Animal {}

public class Test {
    public static void main(String[] args) {
        Human human = new Human();
        human.cao();	// mammal 艸
    }
}
// 介面沖突
interface Animal {
    default void cao() {
        System.out.println("animal 艸");
    }
}

interface Mammal {
    default void cao() {
        System.out.println("mammal 艸");
    }
}

class Human implements Mammal, Animal {
    // 必須重寫方法
    @Override
    public void cao() {
        System.out.println("human 艸");
    }
}

public class Test {
    public static void main(String[] args) {
        Human human = new Human();
        human.cao();
    }
}

2.2 介面中的靜態方法

public class Test {
    public static void main(String[] args) {
        Animal.cao();
    }
}

interface Animal {
    // 必須要有方法體
    static void cao() {
        System.out.println("animal 艸");
    }
}

3、函式式介面

并不是所有的介面都可以使用 Lambda 運算式來實作,只有函式式介面才能寫成 Lambda 運算式

  • 函式式介面:要求介面中定義的必須要實作的抽象方法只能有一個
// 該注解修飾函式式介面,即意味著介面中的抽象方法只能有一個,否則編譯器會報錯
// default方法和靜態方法不會造成任何影響
@FunctionalInterface
interface Animal {
    void cao();
    
    default void ri() {
        System.out.println("日");
    }

    static void shit() {
        System.out.println("shit");
    }
}

4、Lambda 運算式

Lambda 運算式是 Java 8 添加的一個新特性,可以認為 Lambda 是一個匿名函式(相似于匿名內部類),作用是回傳一個實作了介面的物件

  • Lambda 運算式是一個匿名函式,主要關注方法的引數串列和方法體
    • ():描述引數串列
    • {}:描述方法體
    • ->:Lambda 運算子,讀作 goes to
// 無參無回傳介面
@FunctionalInterface
interface 無參無返 {
    void test();
}

// 單參無回傳值介面
@FunctionalInterface
interface 單參無返 {
    void test(int i);
}

// 多參無回傳值介面
@FunctionalInterface
interface 多參無返 {
    void test(int a, int b);
}

// 無參有回傳值介面
@FunctionalInterface
interface 無參有返 {
    int test();
}

// 單參有回傳值介面
@FunctionalInterface
interface 單參有返 {
    int test(int i);
}

// 多參有回傳值介面
@FunctionalInterface
interface 多參有返 {
    int test(int a, int b);
}

public class Test {
    public static void main(String[] args) {
        無參無返 l1 = () -> {
            System.out.println("無參無回傳值");
        };
        l1.test();

        單參無返 l2 = (int i) -> {
            System.out.println("單參無回傳值");
        };
        l2.test(2);

        多參無返 l3 = (int a, int b) -> {
            System.out.println("多參無回傳值");
        };
        l3.test(3, 3);

        無參有返 l4 = () -> {
            System.out.println("無參有回傳值");
            return 4;
        };
        int l4Result = l4.test();

        單參有返 l5 = (int i) -> {
            System.out.println("單參有回傳值");
            return 5;
        };
        int l5Result = l5.test(5);

        多參有返 l6 = (int a, int b) -> {
            System.out.println("多參有回傳值");
            return 6;
        };
        int l6Result = l6.test(6, 6);
    }
}

4.1 Lambda 運算式語法精簡

4.1.1 引數型別的省略

由于在介面中已經定義了引數,所以在 Lambda 運算式中引數的型別可以省略

  • 如果省略引數的型別,則所有的引數的型別都要省略
多參無返 l3 = (int a, int b) -> {
    System.out.println("多參無回傳值");
};
// 省略引數型別
多參無返 l3 = (a, b) -> {
    System.out.println("多參無回傳值");
};

4.1.2 引數小括號的省略

如果引數串列中,引數的個數有且只有一個,那么小括號可以省略,且仍然可以省略引數的型別

單參無返 l2 = (i) -> {
    System.out.println("單參無回傳值");
};
// 省略小括號
單參無返 l2 = i -> {
    System.out.println("單參無回傳值");
};

4.1.3 方法體大括號的省略

如果方法體只有一條陳述句,那么此時大括號可以省略

單參無返 l2 = i -> {
    System.out.println("單參無回傳值");
};
// 省略大括號
單參無返 l2 = i -> System.out.println("單參無回傳值");

4.1.4 return 的省略

如果方法體 只有一條陳述句,且是回傳陳述句,可以省略 return,且必須要省略大括號

單參有返 l5 = i -> {
    return 5;
};

單參有返 l5 = i -> 5;

4.2 方法參考

方法參考是 Lambda 運算式一種簡寫的方式,提供了一種參考而不執行方法的方式,用來直接訪問類或者實體的已經存在的方法或者構造方法,使用時方法參考會創建函式式介面的一個實體

  • 回傳值的型別和引數串列要與介面中定義的一致
public class Test {
    public static void main(String[] args) {
        // 每次使用都實作相同的方法,則非常冗余
        單參有返 l1 = i -> i * 2;
        單參有返 l2 = i -> i * 2;
        
        // 一般的方法呼叫:將Lambda運算式的實作指向change方法
        單參有返 l3 = i -> Method.change(i);
        單參有返 l4 = i -> new Method().change2(i);
        
        // 方法參考:參考方法隸屬者的change方法
        // 方法隸屬者:靜態方法隸屬者為類,非靜態方法的隸屬者是物件
        單參有返 l5 = Method::change;
        單參有返 l6 = new Method()::change2;
    }
}

class Method {
    static int change(int i) {
        return i * 2;
    }

    int change2(int i) {
        return i * 2;
    }
}

4.2.1 構造方法的參考 類名::new

public class Test {
    public static void main(String[] args) {
        // 無參構造方法呼叫
        HumanCreate1 hc1 = () -> new Human();
        hc1.getHuman();
        // 無參構造方法參考
        HumanCreate1 hc1$ = Human::new;
        hc1$.getHuman();

        // 有參構造方法呼叫
        HumanCreate2 hc2 = (String name, int age) -> new Human(name, age);
        hc2.getHuman("特朗普", 18);
        // 有參構造方法參考
        HumanCreate2 hc2$ = Human::new;
        hc2$.getHuman("特朗普", 18);
    }
}

class Human {
    String name;
    int age;

    Human() {
        System.out.println("無參");
    }

    public Human(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有參");
    }
}

interface HumanCreate1 {
    Human getHuman();
}

interface HumanCreate2 {
    Human getHuman(String name, int age);
}

更多:Java-Lambda運算式和“方法參考”的對比和詳解

5、擴展注解

Java 8 擴展了注解的背景關系,現在幾乎可以在任何地方添加注解

public @Deprecated class Test {

    @Retention( RetentionPolicy.RUNTIME )
    @Target( { ElementType.TYPE_USE, ElementType.TYPE_PARAMETER } )
    public @interface NonEmpty {
    }

    public @Deprecated void show() {}

    private void say(@NonEmpty String s) {}

    void see() throws @NonEmpty Exception {

        List<@NonEmpty String> list = new @NonEmpty ArrayList<>();

        throw new @NonEmpty Exception();
    }
}

6、重復注解

Java 8 引入了重復注解機制,在之前使用相同的注解在同一位置只能宣告一次,不能宣告多次

  • 重復注解機制本身必須用 @Repeatable 注解,其實底層原理并沒有改變,更多的是編譯器的技巧
public class Test {
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Filters {
        Filter[] value();
    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    // 重復注解
    @Repeatable(Filters.class)
    public @interface Filter {
        String value();
    }

    @Filter("filter1")
    @Filter("filter2")
    class filter {}
}

更多:Java 8新特性終極指南

7、Optional

Java 8 為了解決 Null 值判斷問題,受到 Google Guava 的啟發,引入了 Optional 類別庫,可以避免顯式的 Null 值判斷

  • Optional 實際上是個容器,可以包裹 Null 或非 Null 的物件

7.1 創建 Optional 物件

// 1、創建一個空的Optional物件
Optional<String> op1 = Optional.empty();

// 2、創建一個物件不可為null的Optional物件,否則報空指標錯誤
Optional<String> op2 = Optional.of("Fuck");

// 3、創建一個物件可以為null的Optional物件
Optional<String> op3 = Optional.ofNullable(null);

7.2 常用方法

public class Test {
    public static void main(String[] args) {
        Person person = new Person("特朗普");

        // get:回傳物件值,如果物件為null則拋出例外
        Person op1 = Optional.of(person).get();
        System.out.println("Optional: " + Optional.of(person));
        System.out.println("get: " + op1);

        // isPresent:判斷物件是否為空,如果物件為null則拋出例外
        boolean op2 = Optional.of(person).isPresent();
        System.out.println("isPresent: " + op2);

        // ifPresent:如果物件不為空,則執行Lambda運算式,否則不做任何處理,沒有回傳值
        Optional.of(person).ifPresent(p -> System.out.println("ifPresent: " + p.name));

        // filter:如果物件值存在并且滿足條件,則回傳滿足條件的Optional,否則回傳empty
        Optional<Person> op3 = Optional.of(person).filter(p -> p.name.length() > 0);
        System.out.println("filter: " + op3);

        // map:如果物件值存在則對其進行提取或轉換值,若結果不為空則回傳Optional,否則回傳empty
        Optional<String> op4 = Optional.of(person).map(p -> "hello " + p.name);
        System.out.println("map: " + op4);

        // flatMap:功能類似map,需要先封裝成Optional
        Optional<String> op5 = Optional.of(person).flatMap(p -> Optional.of(p.name));
        System.out.println("flatMap: " + op5);

        // orElse:如果物件值存在則回傳物件值,否則回傳傳入的值(默認值)
        Person op6 = Optional.of(person).orElse(new Person("安倍晉三"));
        System.out.println("orElse: " + op6);

        // orElseGet:功能類似orElse,可以使用Lambda運算式
        Person op7 = Optional.of(person).orElseGet(() -> new Person("安倍晉三"));
        System.out.println("orElseGet: " + op7);
    }
}

class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "name=" + name;
    }
}

Optional: Optional[name=特朗普]
get: name=特朗普
isPresent: true
ifPresent: 特朗普
filter: Optional[name=特朗普]
map: Optional[hello 特朗普]
flatMap: Optional[特朗普]
orElse: name=特朗普
orElseGet: name=特朗普

更多:理解、學習與使用 Java 中的 Optional

8、Stream

Java 8 引入 Stream 流,讓開發者能夠以宣告的方式處理資料源

  • Stream 操作分為中間操作或者最終操作兩種

    • 終端操作會回傳一個結果
    • 中間操作會回傳一個 Stream 流
  • Stream 的資料源只能 Collection 的子類,List 或者 Set,不支持 Map

  • Stream 的操作可以串行執行(Stream)或者并行執行(parallelStream)

8.1 常用方法

public class Test {
    public static void main(String[] args) {
        List<String> list = getList();

        // forEach:回圈遍歷,沒有回傳值
        list.stream().forEach(s -> System.out.print(s + " "));

        // filter:過濾,回傳符合條件的結果
        Stream<String> st1 = list.stream().filter(s -> s.length() > 2);

        // sorted:排序,可以傳入Comparator進行自定義排序
        Stream<String> st2 = list.stream().sorted();

        // map:中間操作,將集合中的所有元素進行處理
        Stream<Integer> st3 =  list.stream().map(String::length);

        // 匹配
        // anyMatch:任意一個元素符合條件
        boolean anyMatch = list.stream().anyMatch(s -> s.length() == 3);
        // allMatch:全部都符合該條件
        boolean allMatch = list.stream().allMatch(s -> s.length() > 0);
        // noneMatch:全部都不符合該條件
        boolean noneMatch = list.stream().noneMatch(s -> s.length() > 4);

        // count:計數
        long count = list.stream().count();

        // reduce:將集合合并為一個值
        Optional<String> optional = list.stream().reduce((s1, s2) -> s1 + " / " + s2);

        // distinct:去重
        list.stream().distinct();

        // limit:回傳前n個元素
        list.stream().limit(3);

        // collect:集合轉換
        // 轉Set
        Set<String> set = list.stream().collect(Collectors.toSet());
        // 轉List
        List<String> strs = list.stream().collect(Collectors.toList());
        // 轉Map
        Map<String, Integer> map = list.stream().collect(Collectors.toMap(Function.identity(),String::length));
        
        // Arrays.stream(T[] array):陣列轉Stream
        Stream<String> st4 = Arrays.stream(new String[]{"one", "two"});
    }

    static List<String> getList() {
        List<String> list = new ArrayList<>();
        list.add("特朗普");
        list.add("默克爾");
        list.add("莫迪");
        list.add("馬克龍");
        list.add("文在寅");
        list.add("普京");
        list.add("約翰遜");
        list.add("安倍晉三");
        return list;
    }
}

更多:【java8新特性】Stream API詳解

8.2 并行流

Stream 流支持串行和并行的,串行流操作是單執行緒操作,并行流是多執行緒操作,能夠充分利用物理機多核 CPU 的優勢,同時處理速度更快

// 使用并行流很簡單,將stream改為parallelStream即可
public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 5000000; i++) {
            UUID uuid = UUID.randomUUID();
            list.add(uuid.toString());
        }

        long beforeStream = System.currentTimeMillis();
        System.out.println(list.stream().sorted().count());
        System.out.println(System.currentTimeMillis() - beforeStream);

        long beforeParallelStream = System.currentTimeMillis();
        System.out.println(list.parallelStream().sorted().count());
        System.out.println(System.currentTimeMillis() - beforeParallelStream);
    }
}

5000000
4849
5000000
2188

  • 可以看出,并行流的效率比串行流快了一倍左右

9、Date API

新的 Date API 除了是不可變類,執行緒安全之外,還多了添加和優化了許多方法,但原有的時間處理方法已經能解決大部分問題,除非考慮執行緒安全的因素,原有的時間 API 已經足夠使用了,另外新的 Date API 用法簡單,使用時百度即可,不做贅述,附上一個寫的不錯的文章

更多:Java 8 新的日期時間 API

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/108197.html

標籤:其他

上一篇:idea啟動springmvc專案時報找不到類

下一篇:整合mybatis與spring

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more