主頁 > 後端開發 > Java基礎(九)——Java8之后重要的新特性

Java基礎(九)——Java8之后重要的新特性

2021-02-22 14:34:19 後端開發

版本說明發布日期
1.0發布文章第一版2021-02-20

文章目錄

  • 前言
  • Java8新特性
    • 函式式介面
    • Lambda運算式
    • 方法參考
      • 類的非靜態方法參考
      • 構造器的參考
      • 陣列的參考
    • Stream介面
      • Stream的常用方法
      • 案例
        • 列印出集合中所有成年人(測驗filter和forEach)
        • 判斷集合中是否都是成年人(測驗noneMatch)
        • 將集合中所有人的年齡累加并列印(測驗map和reduce)
    • Optional類
      • 來個栗子
  • Java9新特性
    • 模塊化
      • 模塊化的使用
    • 震驚!匿名內部類泛型還能優化?到底是怎么回事呢?讓我們一起來看一看吧~
    • 集合工廠方法
    • 流拷貝方法
  • Java10新特性
    • 區域變數型別推斷

前言

  • 這篇文章是我個人的學習筆記,可能無法做到面面俱到,也可能會有各種紕漏,如果任何疑惑的地方,歡迎一起討論~
  • 如果想完整閱讀這個系列的文章,歡迎關注我的專欄《Java基礎系列文章》~

Java8新特性

  • Java8是一個重要版本,雖然該版本早于2014年發布,但是目前依然有很多企業(比如俺滴老東家)依然在使用,
  • 這個版本對包含語言、編譯器、庫、工具和JVM等在內的各個方面的增添了十多個新特性,尤其是圍繞“函式式介面”,搞出了很多新鮮玩意兒,

函式式介面

  • 別看這個名字花里胡哨的,其實就是指有且僅有一個抽象方法的介面,這類介面在Java8之前其實也接觸過一些,比如多執行緒常用的java.lang.Runnable以及集合中常用的“輔助”java.util.Comparator等,
  • Java8開始,java對函式式介面增加了一個預制注解@FunctionalInterface,當給介面加上了給注解,則在介面不滿足函式式介面時,會出現報錯,
  • 此外,Java8專門增加了一個包java.util.function,該包中包含了很多Java官方提供的函式式介面,
  • 下面列舉一些常用的:
介面名稱介面方法功能介紹
Consumervoid accept(T t)用于實作有一個引數,但沒有回傳值的方法,
SupplierT get()用于實作沒有引數和回傳值的方法,
Function<T,R>R apply(T t)用于實作有引數和回傳值的方法,
Predicateboolean test(T t)用于實作有引數和回傳值,并且回傳值是布爾型別的方法,

Lambda運算式

  • Java8專門為函式式介面的實作和實體化提供了一個語法糖——Lambda運算式,當然,Lambda運算式并不是僅僅用于此的語法糖,也不是匿名內部類的語法糖,
  • 看過我之前文章的小伙伴應該對這個不陌生了,其寫法是:介面名 變數名 = (引數串列) -> {方法體};
  • 舉個栗子:
        Function<String, String> consumer = (String str) -> {
            return str;
        };
  • 此外,Lambda運算式在基礎語法之上,還有些地方可以省略:
    • 引數串列中的變數型別始終可以省略,(因為重寫介面方法,變數型別都是已知的啦);
    • 當引數串列中有且僅有一個引數時,()可以省略;
    • 當且僅當方法體只有一行代碼時,{}可以省略;
    • 當且僅當方法體只有一行代碼,且這一行代碼是一個return時,{}和return關鍵字都可以省略,
  • 所以,上面的栗子可以簡化成下面這樣,emmm,可能看起來有點過分了,但卻是就是可以這么簡單,
        Function<String, String> consumer = str -> str;

方法參考

  • 這個也是針對函式式介面新增的語法糖,
  • 先說說這玩意兒的意義吧,在特定場景下,我們可以把各路英雄齊聚一堂,也就是把來自各個類的方法聚集在一起,提取到同一個介面下面,從而可以很方便地利用多型,來對這些方法進行呼叫,例如下面要講的流(這個流指的是Java8新出的特性,并不是大家熟知的輸入輸出流哈),
  • 所謂方法參考,就是當函式式介面的實作方法中,只有一個方法呼叫或物件創建,則可以通過方法參考來簡化代碼,
  • 說起來有點抽象,大概就是下面這種感覺:
public class LambdaTest {
    public static void main(String[] args) {
        //正常的Lambda運算式寫法
        Consumer<String> consumer = str -> System.out.println(str);
        consumer.accept("Lambda寫法");

        //方法參考寫法
        Consumer<String> consumer1 = System.out::println;
        consumer1.accept("方法參考寫法");
    }
}
  • 下面來具體列舉一下各種情況,由此可見,上面這個例子,就是物件的非靜態方法參考,因為out是一個列印流物件,而println是這個物件的一個成員方法,
種類語法
物件的非靜態方法參考ObjectName :: MethodName
類的靜態方法參考ClassName :: StaticMethodName
類的非靜態方法參考ClassName :: MethodName
構造器的參考ClassName :: new
陣列的參考TypeName[] :: new
  • 對于前兩種,都很好理解,但后面三種怎么用?請待我徐徐道來~

類的非靜態方法參考

  • 當我們重寫的方法中的一個入參作為非靜態方法的呼叫物件,則可以使用類的非靜態方法參考,
  • 舉例如下,運行結果不重要,就不放了,因為o1是Integer入參之一,并且在方法體中是方法的呼叫者,所以可以如下簡化,
public class LambdaTest {
    public static void main(String[] args) {
        //這是最簡單的匿名內部類寫法
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        };
        System.out.println(comparator.compare(1, 2));

        //類的非靜態方法參考,
        comparator = Integer::compare;
        System.out.println(comparator.compare(2, 1));
    }
}

構造器的參考

  • 當重寫的方法中,僅有一行new物件的陳述句,則可以如下簡化:
public class LambdaTest {
    public static void main(String[] args) {
        //這是最簡單的匿名內部類寫法
        Supplier<Person> supplier = new Supplier<Person>() {
            @Override
            public Person get() {
                return new Person();
            }
        };
        System.out.println(supplier.get());

        //通過構造器的參考實作
        supplier = Person::new;
        System.out.println(supplier.get());
    }
}

陣列的參考

  • 當重寫的方法中,僅有一行創建并回傳陣列物件的陳述句,則可以如下簡化:
public class LambdaTest {
    public static void main(String[] args) {
        //這是最簡單的匿名內部類寫法
        Function<Integer, Integer[]> function = new Function<Integer, Integer[]>() {
            @Override
            public Integer[] apply(Integer integer) {
                return new Integer[integer];
            }
        };
        System.out.println(Arrays.toString(function.apply(5)));

        //簡化后
        function = Integer[]::new;
        System.out.println(Arrays.toString(function.apply(2)));
    }
}

Stream介面

  • 位于java.util.stream
  • 該介面對集合的增強,可以對集合元素進行復雜的查找、過濾、篩選等操作,
  • Stream介面借助于Lambda運算式和方法參考,極大提高編程效率和程式可讀性,同時它提供串行和并行兩種模式進行匯聚操作,并發模式能夠充分利用多核處理器的優勢,
  • Stream的使用基本就固定的三個步驟:
    1. 使用一個資料源創建Stream物件;
    2. 對Stream進行各種處理;
    3. 對Stream呼叫終止操作,以回傳結果,

Stream的常用方法

  • Stream的創建方式通常有以下三種:
    • 通過集合物件中新增的獲取流的方法:Stream stream()
    • 通過陣列工具類中的靜態方法,例如:static IntStream stream(int[] array)
    • 通過Stream介面的靜態方法:static Stream of(T... values)static Stream generate(Supplier<? extends T> s)等,
  • Stream的邏輯處理方法:
方法宣告功能介紹
Stream ?lter(Predicate<? super T> predicate)回傳一個包含匹配元素的流
Stream distinct()回傳去重之后的流
Stream limit(long maxSize)回傳最多前指定數量個元素的流
Stream skip(long n)回傳跳過前n個元素后的流
Stream map(Function<? super T,? extends R> mapper)回傳對每個元素處理之后,新元素組成的流,也就是所謂的映射,
Stream sorted()回傳自然排序后的流
Stream sorted(Comparator<? super T> comparator)回傳比較器排序后的流
  • Stream的終止操作:
方法宣告功能介紹
Optional ?ndFirst()回傳該流的第一個元素
boolean allMatch(Predicate<? super T> predicate)判斷所有元素是否匹配指定條件
boolean noneMatch(Predicate<? super T> predicate)判斷所有元素是否不匹配指定條件
Optional max(Comparator<? super T> comparator)根據比較器回傳最大元素
Optional min(Comparator<? super T> comparator)根據比較器回傳最小元素
long count()回傳元素的個數
void forEach(Consumer<? super T> action)對流中每個元素執行指定操作
Optional reduce(BinaryOperator accumulator)將集合中所有元素結合

案例

列印出集合中所有成年人(測驗filter和forEach)

  • 我這里就不用傳統的寫法了,直接看看在Java8之后,我們可以如何實作這樣的需求:
//首先構造一個測驗用的Person類
public class Person {
    private int age;
    private String name;

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

//然后是測驗方法
public class Starter {
    public static void main(String[] args) {
        getAdults();
    }

    public static void getAdults() {
        //創建用于測驗的集合
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person(17, "豬豬俠"));
        list.add(new Person(20, "蜘蛛俠"));
        list.add(new Person(23, "咕咕俠"));
        list.add(new Person(30, "大俠"));

        //先用比較容易理解的匿名內部類來實作,便于理解,
        //首先獲取list的流物件
        //然后呼叫filter方法,實作Predicate介面,
        list.stream().filter(new Predicate<Person>() {
            @Override
            public boolean test(Person person) {
                return person.getAge() >= 18;
            }
        }).forEach(new Consumer<Person>() {
            @Override
            public void accept(Person person) {
                System.out.println(person);
            }
        });

        //使用方法參考和Lambda運算式來簡化
        System.out.println("====================");
        list.stream().filter(person -> person.getAge() >= 18).forEach(System.out::println);
    }
}
  • 運行結果如下,方法參考、Lambda運算式和Stream的強大之處就不需要我多言了吧~如果我們用傳統的迭代器來實作,還需要for回圈啦,各種blabla的操作,在Java8加持之下,只需要一行代碼就能實作需求,一個字:爽!
Person{age=20, name='蜘蛛俠'}
Person{age=23, name='咕咕俠'}
Person{age=30, name='大俠'}
====================
Person{age=20, name='蜘蛛俠'}
Person{age=23, name='咕咕俠'}
Person{age=30, name='大俠'}

判斷集合中是否都是成年人(測驗noneMatch)

  • 這個案例呢就得用到noneMatch或者match方法了,但是實作步驟還是大同小異,代碼如下,Person類一樣的,就省略了,
    public static void isAdults() {
        //創建用于測驗的集合
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person(17, "豬豬俠"));
        list.add(new Person(20, "蜘蛛俠"));
        list.add(new Person(23, "咕咕俠"));
        list.add(new Person(30, "大俠"));

        //先用比較容易理解的匿名內部類來實作,便于理解,
        boolean result = list.stream().noneMatch(new Predicate<Person>() {
            @Override
            public boolean test(Person person) {
                return person.getAge() < 18;
            }
        });
        System.out.println("都是成年人嗎?" + result);

        //使用方法參考和Lambda運算式來簡化
        System.out.println("====================");
        result = list.stream().noneMatch(person -> person.getAge() < 18);
        System.out.println("都是成年人嗎?" + result);
    }
  • 運行結果如下,講這個例子主要是怕小伙伴們沒有理解noneMatch是什么意思,當集合中沒有任何元素匹配判斷條件時,noneMatch就會回傳true,否則回傳false,
都是成年人嗎?false
====================
都是成年人嗎?false

將集合中所有人的年齡累加并列印(測驗map和reduce)

  • 通過map方法,可以重新映射出一個由年齡組成的流,而reduce方法可以對集合中所有元素進行二元處理(比如累加),
    public static void sumAge(){
        //創建用于測驗的集合
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person(17, "豬豬俠"));
        list.add(new Person(20, "蜘蛛俠"));
        list.add(new Person(23, "咕咕俠"));
        list.add(new Person(30, "大俠"));

        //先用比較容易理解的匿名內部類來實作,便于理解,
        //先將集合映射為年齡集合,因為年齡是整數,所以需要使用Integer來存放
        //再用reduce來累加年齡
        Optional<Integer> result = list.stream().map(new Function<Person, Integer>() {
            @Override
            public Integer apply(Person person) {
                return person.getAge();
            }
        }).reduce(new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer, Integer integer2) {
                return integer + integer2;
            }
        });
        System.out.println(result);

        //使用方法參考和Lambda運算式來簡化
        System.out.println("====================");
        result = list.stream().map(Person::getAge).reduce(Integer::sum);
        System.out.println(result);
    }
  • 執行結果如下,
    • 至于Optional類是什么個東西,下面馬上會講,
    • BinaryOperator是BiFunction的子介面,也是一個函式式介面,用于將兩個同型別入參轉換為一個同型別的回傳值,
    • 所以reduce是什么作用呢,也就可見一斑了,就是通過二元處理,來將集合中所有的元素,處理為一個元素,
Optional[90]
====================
Optional[90]

Optional類

  • 位于java.util,是一個容器,主要用于處理可能為空的物件,以簡化傳統的通過if/else判空代碼,
  • 常用的方法如下:
方法宣告功能介紹
static Optional ofNullable(T value)根據引數創建物件,
Optional map(Function<? super T,? extends U> mapper)將Optional物件映射為另一種Optional物件,
T orElse(T other)回傳物件中的值,否則回傳other指定的值,

來個栗子

  • 提供一個方法,列印字串的長度,如果字串為空,則長度視為0,
  • 如果使用傳統的判斷,就不夠簡潔,java8之后我們就可以用Optional來搞:
public class OptionalTest {
    public static void main(String[] args) {
        StringLength("12341324");
        StringLength(null);
    }

    public static void StringLength(String str){
        //創建Optional物件
        Optional<String> optionalS = Optional.ofNullable(str);

        //映射為字串長度,并且獲取回傳值
        System.out.println(optionalS.map(String::length).orElse(0));
    }
}
  • 運行結果如下,就兩行代碼就實作了,不服不行啊!順道一提,Java11中String類也增加了orElse方法,用法是一模一樣的,
8
0

Java9新特性

模塊化

  • 隨著java的發展,一個專案的大小越來越大,導致啟動或者運行的時候效率下降,例如多時候,一些代碼之間聯系性很高,而一些代碼之間聯系性很低,如果同一時間都將他們全部放在一起管理、運行,會導致效率的低下,
  • 為了解決這個問題,java9引入了模塊化,同一個專案下面可以有多個模塊,不同模塊之間是相互獨立的,資源的加載也是分開的,從而減少記憶體的開銷,提高專案的可維護性,

模塊化的使用

  1. 對于IDEA編譯器,可以通過在專案上右鍵直接創建模塊

創建模塊

  1. 給模塊更改名字和路徑

模塊名

  1. 建好之后,兩個模塊就分別會有自己的源路徑src,默認情況下,不同的模塊之間的類無法相互訪問,那如果我們想訪問另一個模塊的類怎么辦呢?這個時候就需要配置一個特殊的模塊資訊檔案,
    • 例如現在想在NewModule模塊訪問JavaPractice模塊的類,則在兩個模塊中如下創建檔案:

創建模塊資訊檔案

  1. 在JavaPractice模塊資訊中寫入如下代碼,將該包暴露給其他模塊,我在這個包下面封裝了一個Person類,待會兒用這個類進行測驗,
module JavaPractice {
    //想要暴露給其他模塊的包使用exports關鍵字來實作
    exports com.JavaSE.NewFeature.Java8.Stream;
}
  1. 在NewModule模塊資訊中寫入如下代碼,以引入JavaPractice模塊,寫好之后會報錯,因為還沒有在專案配置中依賴JavaPractice模塊,根據修改意見add dependency就好,
module NewModule {
    //需要依賴的模塊使用requires關鍵字來實作
    requires JavaPractice;
}
  1. 在NewModule中創建一個測驗類,如下,
package com;

import com.JavaSE.NewFeature.Java8.Stream.Person;

public class Starter {
    public static void main(String[] args) {
        Person person = new Person(12, "帥");
        System.out.println(person);
    }
}
  1. 運行結果如下,可以看到這樣就能使用其他模塊的類了,
Person{age=12, name='帥'}

震驚!匿名內部類泛型還能優化?到底是怎么回事呢?讓我們一起來看一看吧~

public class GenericityOptimization {
    public static void main(String[] args) {
        //以前的寫法
        Function<String, String> function = new Function<String, String>() {
            @Override
            public String apply(String s) {
                return null;
            }
        };

        //java9的優化
        function = new Function<>() {
            @Override
            public String apply(String s) {
                return null;
            }
        };
    }
}
  • 看到區別了么?其實就是實體化陳述句的泛型可以省略了(因為必須得一樣嘛),所以其實就是很小的一個優化,一看就是老營銷號了,

集合工廠方法

  • Java9給集合增加了靜態工廠方法of,該方法創建的集合物件的元素是不可新增、洗掉和修改的,并且集合中的元素不能為null,
  • 簡單測驗一下:
public class CollectionTest {
    public static void main(String[] args) {
        List<String> list = List.of("null", "123");
        System.out.println(list);

        //假如想添加一個元素
        list.add("哇哦");
    }
}
  • 運行結果如下,當添加的元素為null或者想對集合中的元素進行修改的時候,編譯不會報錯,但是運行時會拋出例外,
[null, 123]
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71)
	at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:75)
	at JavaPractice/com.JavaSE.NewFeature.Java9.CollectionTest.main(CollectionTest.java:11)

流拷貝方法

  • 看過我之前講流的小伙伴,肯定會對流拷貝的例子有印象,好訊息!Java9把這個方法封裝啦!到時候我們直接一個方法呼叫就完事兒~這個方法就是InputStream的transferTo,
  • 來看個例子就懂啦~流的copy so easy!
public class StreamTest {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("D:\\吉他譜\\這一生關于你的風景\\這一生關于你的風景1.png");
        OutputStream outputStream = new FileOutputStream("D:\\吉他譜\\這一生關于你的風景\\test.png");

        //以前的話我們得在這兒用緩沖流寫一堆拷貝的方法,現在直接一個方法呼叫就OK
        inputStream.transferTo(outputStream);
        
        inputStream.close();
        outputStream.close();
    }
}

Java10新特性

  • Java10其實是一個比較小的“大版本”,其中有兩個比較關鍵的變更:區域變數型別推斷和垃圾回收器的增強,不過垃圾回收涉及到JVM了,我還不太了解,所以這里就不講啦,

區域變數型別推斷

  • 有時候變數型別寫起來會覺得好麻煩,于是Java10看不下去了,就整了個新活,
  • Java10可以使用var來代替變數型別,僅適用于有初始值的區域變數、增強for回圈的索引和傳統for回圈的回圈變數,不能使用于方法形參、方法回傳型別、catch形參或任何其他型別的變數宣告,
  • var不是關鍵字,意味著var可以繼續用于方法名、包名,但var不能作為類或則介面的名字,
  • 給個栗子:
public class VarTest {
    public static void main(String[] args) {
        //代替區域變數型別
        var list = new ArrayList<String>();

        //代替增強for回圈索引
        for(var str:list){

        }

        //代替傳統for回圈的回圈變數
        for(var i = 0;i < list.size();i++){
            
        }
    }
}

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

標籤:java

上一篇:PyQt5入門(二十八)用PyInstaller打包PyQt5應用 & 使用PyQtGraph進行資料可視化

下一篇:【演算法導論】筆記-第八章中位數和排序統計量

標籤雲
其他(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