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

Java中的Stream流與IO流完整實(shí)戰(zhàn)指南(從零掌握)

 更新時(shí)間:2025年11月19日 14:32:16   作者:努力中的馬嘍  
本文詳細(xì)介紹了Java中的Stream流和IO流的使用方法,包括它們的基本概念、核心API、適用場景以及如何正確關(guān)閉資源,通過多個(gè)實(shí)戰(zhàn)案例,幫助讀者掌握這些核心技能,提高Java開發(fā)效率,感興趣的朋友跟隨小編一起看看吧

Java新手必會(huì):Stream流與IO流完整實(shí)戰(zhàn)指南

核心觀點(diǎn):掌握J(rèn)ava的Stream流和IO流,就像學(xué)會(huì)了兩把"數(shù)據(jù)處理神器"——Stream流讓集合操作變得優(yōu)雅高效,IO流讓文件讀寫不再頭疼。本文將用最接地氣的方式,帶你從零到一掌握這兩大核心技能。

1. 什么是Stream流和IO流?一句話說清楚

Stream流(集合流)

一句話理解:把集合中的數(shù)據(jù)想象成流水線上的產(chǎn)品,Stream流就是這條流水線,可以對數(shù)據(jù)進(jìn)行篩選、加工、組裝。

生活例子:就像奶茶店制作奶茶的過程——原料(集合)→ 篩選茶葉(filter)→ 加糖(map)→ 打包(collect),一氣呵成!

IO流(輸入輸出流)

一句話理解:IO流是Java讀寫文件、網(wǎng)絡(luò)傳輸數(shù)據(jù)的通道,就像水管輸送水一樣。

生活例子:你用U盤拷貝文件,IO流就是那根"看不見的數(shù)據(jù)線",負(fù)責(zé)把數(shù)據(jù)從硬盤"運(yùn)"到U盤。

2. Stream流:讓集合操作像流水線一樣順暢

2.1 Stream流的三大核心優(yōu)勢

  1. 代碼簡潔:一行代碼搞定原本需要好幾個(gè)for循環(huán)的操作
  2. 鏈?zhǔn)秸{(diào)用:filter、map、sorted一氣呵成,邏輯清晰
  3. 延遲執(zhí)行:只有調(diào)用終止操作(如collect)時(shí)才真正執(zhí)行,性能更優(yōu)

2.2 核心API實(shí)戰(zhàn)

案例1:篩選出成績大于60分的學(xué)生
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamDemo1 {
    public static void main(String[] args) {
        // 學(xué)生成績列表
        List<Integer> scores = new ArrayList<>();
        scores.add(85);
        scores.add(45);
        scores.add(92);
        scores.add(58);
        scores.add(73);
        // 使用Stream流篩選及格的成績
        List<Integer> passedScores = scores.stream()
                .filter(score -> score >= 60)  // 篩選:保留>=60的成績
                .collect(Collectors.toList()); // 收集結(jié)果
        System.out.println("及格成績:" + passedScores);
        // 輸出:及格成績:[85, 92, 73]
    }
}

代碼講解

  • stream():將集合轉(zhuǎn)換為流
  • filter():過濾數(shù)據(jù),參數(shù)是Lambda表達(dá)式
  • collect(Collectors.toList()):將流收集回List
案例2:將所有學(xué)生姓名轉(zhuǎn)為大寫
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamDemo2 {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("zhangsan", "lisi", "wangwu");
        // 將姓名轉(zhuǎn)為大寫
        List<String> upperNames = names.stream()
                .map(String::toUpperCase)  // 轉(zhuǎn)換:每個(gè)元素調(diào)用toUpperCase()
                .collect(Collectors.toList());
        System.out.println("大寫姓名:" + upperNames);
        // 輸出:大寫姓名:[ZHANGSAN, LISI, WANGWU]
    }
}

代碼講解

  • map():轉(zhuǎn)換操作,將每個(gè)元素映射成新的值
  • String::toUpperCase:方法引用,等價(jià)于 name -> name.toUpperCase()
案例3:統(tǒng)計(jì)平均分
import java.util.Arrays;
import java.util.List;
public class StreamDemo3 {
    public static void main(String[] args) {
        List<Integer> scores = Arrays.asList(85, 92, 78, 90, 88);
        // 計(jì)算平均分
        double average = scores.stream()
                .mapToInt(Integer::intValue)  // 轉(zhuǎn)換為IntStream
                .average()                     // 求平均值
                .orElse(0.0);                 // 如果流為空,返回0.0
        System.out.println("平均分:" + average);
        // 輸出:平均分:86.6
    }
}

代碼講解

  • mapToInt():將Stream轉(zhuǎn)為IntStream,可以使用數(shù)值操作
  • average():返回OptionalDouble,避免空指針
  • orElse():提供默認(rèn)值
案例4:去重并排序
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamDemo4 {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(5, 2, 8, 2, 9, 1, 5, 8);
        // 去重、排序、收集
        List<Integer> result = numbers.stream()
                .distinct()                    // 去重
                .sorted()                      // 排序(默認(rèn)升序)
                .collect(Collectors.toList());
        System.out.println("去重排序后:" + result);
        // 輸出:去重排序后:[1, 2, 5, 8, 9]
    }
}

3. 字節(jié)流 vs 字符流:該用哪個(gè)?看這里就夠了

3.1 核心區(qū)別一覽表

對比項(xiàng)字節(jié)流字符流
處理單位字節(jié)(byte,8位)字符(char,16位)
適用場景圖片、視頻、音頻等二進(jìn)制文件文本文件(.txt、.java等)
核心類InputStream / OutputStreamReader / Writer
是否有緩沖無(需手動(dòng)包裝)無(需手動(dòng)包裝)

3.2 字節(jié)流實(shí)戰(zhàn):復(fù)制圖片

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo {
    public static void main(String[] args) {
        // 使用 try-with-resources 自動(dòng)關(guān)閉資源
        try (
            FileInputStream fis = new FileInputStream("source.jpg");
            FileOutputStream fos = new FileOutputStream("target.jpg")
        ) {
            byte[] buffer = new byte[1024];  // 緩沖區(qū)
            int len;
            // 循環(huán)讀取并寫入
            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            System.out.println("圖片復(fù)制成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代碼講解

  • FileInputStream:文件字節(jié)輸入流,用于讀取
  • FileOutputStream:文件字節(jié)輸出流,用于寫入
  • read(buffer):一次讀取最多buffer.length個(gè)字節(jié),返回實(shí)際讀取的字節(jié)數(shù)
  • -1表示讀到文件末尾
  • try-with-resources:JDK7新特性,自動(dòng)關(guān)閉資源

3.3 字符流實(shí)戰(zhàn):讀寫文本文件

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharStreamDemo {
    public static void main(String[] args) {
        // 寫入文本
        try (FileWriter fw = new FileWriter("hello.txt")) {
            fw.write("你好,Java IO流!\n");
            fw.write("這是第二行內(nèi)容。");
            System.out.println("文件寫入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 讀取文本
        try (FileReader fr = new FileReader("hello.txt")) {
            int ch;
            while ((ch = fr.read()) != -1) {
                System.out.print((char) ch);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代碼講解

  • FileWriter:字符輸出流,適合寫文本
  • FileReader:字符輸入流,適合讀文本
  • read():一次讀一個(gè)字符,返回int(-1表示結(jié)束)

4. 緩沖流:性能提升10倍的秘密武器

4.1 為什么需要緩沖流?

問題:每次讀寫都直接訪問硬盤,就像你去超市買菜,買一根蔥就跑一趟,效率極低!

解決方案:緩沖流內(nèi)置一個(gè)緩沖區(qū)(默認(rèn)8KB),相當(dāng)于帶個(gè)購物車,攢夠一車再去收銀臺(tái),大大減少IO次數(shù)。

4.2 緩沖字節(jié)流實(shí)戰(zhàn)

import java.io.*;
public class BufferedByteStreamDemo {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        try (
            BufferedInputStream bis = new BufferedInputStream(
                new FileInputStream("large_file.zip")
            );
            BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("large_file_copy.zip")
            )
        ) {
            byte[] buffer = new byte[8192];  // 8KB緩沖區(qū)
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            long endTime = System.currentTimeMillis();
            System.out.println("復(fù)制完成,耗時(shí):" + (endTime - startTime) + "ms");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

性能對比

  • 普通字節(jié)流:1000ms
  • 緩沖字節(jié)流:100ms(提升10倍)

4.3 緩沖字符流實(shí)戰(zhàn):按行讀寫

import java.io.*;
public class BufferedCharStreamDemo {
    public static void main(String[] args) {
        // 按行寫入
        try (BufferedWriter bw = new BufferedWriter(
                new FileWriter("students.txt")
        )) {
            bw.write("張三,85");
            bw.newLine();  // 寫入換行符(跨平臺(tái))
            bw.write("李四,92");
            bw.newLine();
            bw.write("王五,78");
            System.out.println("學(xué)生信息寫入成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 按行讀取
        try (BufferedReader br = new BufferedReader(
                new FileReader("students.txt")
        )) {
            String line;
            while ((line = br.readLine()) != null) {  // 按行讀取
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代碼講解

  • BufferedWriter.newLine():寫入換行符,自動(dòng)適配不同操作系統(tǒng)
  • BufferedReader.readLine():按行讀取,讀到末尾返回null

5. 資源釋放:不注意這點(diǎn)會(huì)出大問題 ??

5.1 為什么必須關(guān)閉流?

后果

  1. 內(nèi)存泄漏:流對象一直占用內(nèi)存
  2. 文件鎖定:文件被占用,無法刪除或重命名
  3. 數(shù)據(jù)丟失:緩沖區(qū)數(shù)據(jù)可能未寫入文件

5.2 正確的資源釋放方式

? 錯(cuò)誤示范(JDK7之前)
FileInputStream fis = null;
try {
    fis = new FileInputStream("data.txt");
    // 讀取操作...
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (fis != null) {
        try {
            fis.close();  // 繁瑣!
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
? 正確示范(JDK7+)
try (FileInputStream fis = new FileInputStream("data.txt")) {
    // 讀取操作...
} catch (IOException e) {
    e.printStackTrace();
}
// 無需手動(dòng)關(guān)閉,try-with-resources自動(dòng)處理

原理:實(shí)現(xiàn)了AutoCloseable接口的類,在try代碼塊結(jié)束時(shí)會(huì)自動(dòng)調(diào)用close()方法。

6. 實(shí)戰(zhàn)案例與常見避坑指南

案例1:讀取配置文件并過濾有效配置

import java.io.*;
import java.util.List;
import java.util.stream.Collectors;
public class ConfigReaderDemo {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(
                new FileReader("config.properties")
        )) {
            // 使用Stream流過濾空行和注釋行
            List<String> validConfigs = br.lines()  // 將所有行轉(zhuǎn)為Stream
                    .map(String::trim)               // 去除首尾空格
                    .filter(line -> !line.isEmpty()) // 過濾空行
                    .filter(line -> !line.startsWith("#")) // 過濾注釋
                    .collect(Collectors.toList());
            System.out.println("有效配置:");
            validConfigs.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

亮點(diǎn):將IO流和Stream流結(jié)合,代碼簡潔優(yōu)雅!

案例2:統(tǒng)計(jì)文本文件中每個(gè)單詞的出現(xiàn)次數(shù)

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
public class WordCountDemo {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(
                new FileReader("article.txt")
        )) {
            Map<String, Long> wordCount = br.lines()
                    .flatMap(line -> Arrays.stream(line.split("\\s+"))) // 按空格分詞
                    .map(String::toLowerCase)  // 轉(zhuǎn)小寫
                    .filter(word -> !word.isEmpty())  // 過濾空字符串
                    .collect(Collectors.groupingBy(
                            word -> word,           // 按單詞分組
                            Collectors.counting()   // 統(tǒng)計(jì)數(shù)量
                    ));
            // 打印詞頻前10的單詞
            wordCount.entrySet().stream()
                    .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                    .limit(10)
                    .forEach(entry -> 
                        System.out.println(entry.getKey() + ": " + entry.getValue())
                    );
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

知識(shí)點(diǎn)整合

  • BufferedReader讀取文件
  • Stream流的flatMap、filter、map
  • Collectors的高級用法(分組、計(jì)數(shù))

常見避坑指南 ??

坑1:忘記關(guān)閉流導(dǎo)致文件鎖定

現(xiàn)象:程序運(yùn)行后無法刪除文件,提示"文件正在使用"

解決:始終使用try-with-resources

坑2:字節(jié)流讀取文本出現(xiàn)亂碼

原因:字節(jié)流不處理字符編碼

解決

// ? 錯(cuò)誤:用字節(jié)流讀中文
FileInputStream fis = new FileInputStream("中文.txt");
// ? 正確:用字符流或指定編碼
BufferedReader br = new BufferedReader(
    new InputStreamReader(new FileInputStream("中文.txt"), "UTF-8")
);
坑3:緩沖流未flush導(dǎo)致數(shù)據(jù)丟失
BufferedWriter bw = new BufferedWriter(new FileWriter("data.txt"));
bw.write("重要數(shù)據(jù)");
// 如果程序崩潰,數(shù)據(jù)可能丟失!
// 解決:手動(dòng)flush或關(guān)閉流
bw.flush();  // 強(qiáng)制刷新緩沖區(qū)
坑4:Stream流多次消費(fèi)
Stream<String> stream = list.stream();
stream.forEach(System.out::println);  // 第一次消費(fèi)
stream.forEach(System.out::println);  // ? 報(bào)錯(cuò):stream已被消費(fèi)

解決:Stream只能消費(fèi)一次,需要重新創(chuàng)建。

7. 核心要點(diǎn)總結(jié) ??

Stream流(集合流)核心要點(diǎn)

? 記住這三步:創(chuàng)建流 → 中間操作(filter/map/sorted)→ 終止操作(collect)

? 常用API速查

  • filter():篩選
  • map():轉(zhuǎn)換
  • distinct():去重
  • sorted():排序
  • limit():限制數(shù)量
  • collect():收集結(jié)果

? 注意事項(xiàng):Stream只能消費(fèi)一次,鏈?zhǔn)秸{(diào)用更高效

IO流核心要點(diǎn)

? 選擇流的黃金法則

  • 文本文件 → 字符流(Reader/Writer)
  • 二進(jìn)制文件 → 字節(jié)流(InputStream/OutputStream)
  • 需要高性能 → 加Buffered包裝

? 四大核心類記憶

場景輸入輸出
字節(jié)流FileInputStreamFileOutputStream
字符流FileReaderFileWriter
緩沖字節(jié)流BufferedInputStreamBufferedOutputStream
緩沖字符流BufferedReaderBufferedWriter

? 資源管理鐵律:永遠(yuǎn)使用try-with-resources,避免內(nèi)存泄漏

實(shí)踐建議

  1. 讀寫文本優(yōu)先用緩沖字符流,性能好且支持按行操作
  2. 復(fù)制文件優(yōu)先用緩沖字節(jié)流,通用性強(qiáng)
  3. 處理集合數(shù)據(jù)優(yōu)先用Stream流,代碼簡潔
  4. 記得指定字符編碼,避免中文亂碼(推薦UTF-8)
  5. 大文件分塊讀取,避免內(nèi)存溢出

結(jié)語

掌握Stream流和IO流,你就解鎖了Java開發(fā)的兩大核心技能:

  • Stream流讓你的集合操作代碼像詩一樣優(yōu)雅
  • IO流讓你的文件處理能力如虎添翼

記住:多動(dòng)手實(shí)踐,把本文的代碼全部運(yùn)行一遍,你會(huì)發(fā)現(xiàn)原來流的世界如此簡單!

到此這篇關(guān)于Java中的Stream流與IO流完整實(shí)戰(zhàn)指南(從零掌握)的文章就介紹到這了,更多相關(guān)java stream流與io流內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA Integer類常用方法解析

    JAVA Integer類常用方法解析

    這篇文章主要介紹了JAVA Integer類常用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • springboot使用hibernate validation對參數(shù)校驗(yàn)的實(shí)現(xiàn)方法

    springboot使用hibernate validation對參數(shù)校驗(yàn)的實(shí)現(xiàn)方法

    這篇文章主要介紹了spring-boot 使用hibernate validation對參數(shù)進(jìn)行優(yōu)雅的校驗(yàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • java 直接調(diào)用python腳本,并傳遞參數(shù)代碼實(shí)例

    java 直接調(diào)用python腳本,并傳遞參數(shù)代碼實(shí)例

    這篇文章主要介紹了java調(diào)用python腳本傳遞參數(shù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Mybatis一對多關(guān)聯(lián)關(guān)系映射實(shí)現(xiàn)過程解析

    Mybatis一對多關(guān)聯(lián)關(guān)系映射實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Mybatis一對多關(guān)聯(lián)關(guān)系映射實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • SpringBoot AOP實(shí)現(xiàn)釘釘+企業(yè)微信雙渠道異常告警

    SpringBoot AOP實(shí)現(xiàn)釘釘+企業(yè)微信雙渠道異常告警

    本文主要介紹了SpringBoot AOP實(shí)現(xiàn)釘釘+企業(yè)微信雙渠道異常告警,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-04-04
  • 淺談一下Java中的訪問修飾符以及作用

    淺談一下Java中的訪問修飾符以及作用

    這篇文章主要介紹了淺談一下Java中的訪問修飾符以及作用,修飾符修飾的是“被訪問”的權(quán)限,所有修飾符都可以修飾成員變量,方法,構(gòu)造方法,需要的朋友可以參考下
    2023-05-05
  • 如何使用@Value和@PropertySource注入外部資源

    如何使用@Value和@PropertySource注入外部資源

    這篇文章主要介紹了如何使用@Value和@PropertySource注入外部資源的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(32)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(32)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • 關(guān)于java單元測試(@Test)詳解

    關(guān)于java單元測試(@Test)詳解

    文章介紹了初學(xué)者在Java中使用Junit進(jìn)行單元測試的環(huán)境配置方法,并說明了如何新建測試類、導(dǎo)入包及運(yùn)行測試程序,簡化了功能驗(yàn)證流程
    2025-10-10
  • Java利用EasyExcel實(shí)現(xiàn)合并單元格

    Java利用EasyExcel實(shí)現(xiàn)合并單元格

    在某些業(yè)務(wù)場景中可能會(huì)有合并單元格的需求,本文將詳細(xì)為大家講解Java如何利用EasyExcel實(shí)現(xiàn)合并單元格,感興趣的小伙伴可以了解一下
    2022-06-06

最新評論

巴彦县| 仁化县| 北流市| 应城市| 泸水县| 微博| 凉城县| 平阳县| 仲巴县| 平乡县| 墨玉县| 略阳县| 绥棱县| 彭州市| 尼木县| 鹤山市| 商城县| 太原市| 岚皋县| 育儿| 扶余县| 海城市| 兰西县| 报价| 土默特右旗| 江津市| 双江| 浑源县| 揭东县| 平江县| 昆山市| 万全县| 南木林县| 清流县| 耿马| 陇川县| 瑞安市| 金昌市| 舞钢市| 新晃| 若尔盖县|