Lambda、Stream流、线程(池)、IO

文章目录

  • Lambda
  • Stream流
  • 线程(池)
  • IO

Lambda

使用前提

  • 必须存在一个接口
  • 接口中有且只有一个抽象方法

格式 : ( 形式参数 ) -> { 代码块 }

  • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
  • ->:由英文中画线和大于符号组成,固定写法。代表指向动作
  • 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
// 函数式接口:只有一个抽象方法的接口   加 @FunctionalInterface
@FunctionalInterface
public interface Calculator {
    public abstract int calculate(int a,int b);
}

/*

    Lambda表达式:简化匿名内部类的代码
    语法:
        (参数列表) -> {方法体}
        参数列表:对应重写方法的参数列表
        方法体:对应重写方法的方法体
        ->:箭头,分割参数列表和方法体
        注意:
            1. 如果参数列表为空,则可以省略小括号
            2. 如果参数列表只有一个参数,则可以省略小括号
            3. 如果方法体只有一行代码,则可以省略大括号和return关键字
            4. 如果方法体只有一行代码,并且是返回值,则可以省略大括号和return关键字
*/

public class CalculatorTest {
    public static void main(String[] args) {

        //使用匿名内部类
        useCalculator(new Calculator() {
            @Override
            public int calculate(int a, int b) {
                System.out.println(a - b);
                return a - b;  // -10
            }
        });

        //使用Lambda表达式
        useCalculator((a, b) -> {
            System.out.println(a + b);
            return a + b;   // 30
        });

        //简化Lambda表达式
        useCalculator((a, b) -> a * b); // 200

    }

    public static void useCalculator(Calculator calculator) {
        calculator.calculate(10, 20);
    }
}

Stream流

获取Stream流

  • 创建一条流水线,并把数据放到流水线上准备进行操作

中间方法

  • 流水线上的操作。
  • 一次操作完毕之后,还可以继续进行其他操作

终结方法

  • 一个Stream流只能有一个终结方法
  • 是流水线上的最后一个操作
/*
    Stream 流
    1. Stream 流是 Java 8 的新特性,它允许我们对数据进行一系列的操作,如过滤、映射、排序等。
    2. Stream 流的使用可以让代码更加简洁、易读,同时提高代码的执行效率。
    3. Stream 流的操作是惰性的,即只有当需要结果时才会执行操作。
    4. Stream 流的操作是链式调用的,即可以在一个流上连续调用多个操作。
    5. Stream 流的操作是中间操作和终止操作,中间操作不会立即执行,而是返回一个新的流,终止操作会立即执行并返回结果。
    6. Stream 流的操作是并行执行的,即可以在多个线程上同时执行操作,提高代码的执行效率。
*/

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class StreamTest {

    public static void main(String[] args) {
        // 集合
        List<Integer> list = new ArrayList<>();

        // 添加元素
        Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 使用 stream 流
        list.stream().sorted().forEach(num -> System.out.println(num));

        list.stream()
                .sorted((num1, num2) -> num2 - num1)
                .forEach(num -> System.out.println(num));

        System.out.println("------------------------");

        List<String> list2 = new ArrayList<>();

        Collections.addAll(list2, "zuo", "shi", "xu", "hebut", "hebust");
        list2.stream()
                .filter(str -> str.length() > 2)
                .filter(str -> str.contains("he"))
                .forEach(str -> System.out.println(str));

    }
}

线程(池)

线程的两种实现方法

  • 继承Thread类
  • 实现Runnable接口 (推荐!!!)
  • 都需要重写run方法
// 继承Thread类
public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 500; i++) {
            System.out.println("hello" + i);
        }
    }
}

// 实现Runnable接口
public class MyThread1 implements Runnable {
    @Override
    public void run() {
        for (int i = 500; i < 1000; i++) {
            System.out.println("world" + i);
        }
    }
}

// main方法
public class ThreadTest {
    public static void main(String[] args) {
        System.out.println("main 方法开始了 ...");

        // 方式1 继承 Thread类
        // 创建任务类对象
        MyThread t1 = new MyThread();
        // 启动线程
        t1.start();

        // 方式2 实现 Runnable接口
        // 创建任务类对象
        MyThread1 t2 = new MyThread1();

        // 创建线程对象
        Thread t3 = new Thread(t2);

        // 启动线程
        t3.start();

        for (int i = 1000; i < 1500; i++) {
            System.out.println("main 方法执行了 " + i);
        }
    }
}

线程安全问题 (访问共享数据的问题)
1. 同步代码块
synchronized(锁对象){}
锁对象 可以是任意对象
2. 同步方法
把访问了共享数据的代码抽取出来,放到一个方法中
使用synchronized修饰这个方法
锁对象 就是this
3. 静态同步方法
把访问了共享数据的代码抽取出来,放到一个静态方法中
使用synchronized修饰这个方法
锁对象 就是 类名.class
4. Lock
new ReentrantLock();
lock.lock(); // 上锁
lock.unlock(); // 开锁

import java.util.concurrent.locks.ReentrantLock;

public class Ticket implements Runnable {
    private int ticket = 100; //票数

    // Lock  推荐
    ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
            try {
                lock.lock();
                if (ticket <= 0) {
                    break;
                }
                if (ticket > 0) {
                    Thread.sleep(100);  // 模拟网络延迟
                    System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
                }
                ticket--;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();  // 永远会执行  不管上面是否有异常  跳出 while也会执行
            }
        }
    }

//    // 自定义锁对象
//    Object lock = new Object();
//
//    @Override
//    public void run() {
//        while (true) {
//            // 同步代码块
//            synchronized (lock) {
//                if (ticket <= 0) {
//                    break;
//                }
//                if (ticket > 0) {
//                    System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
//                }
//                ticket--;
//            }
//        }
//    }

//    @Override
//    public void run() {
//        while (true) {
//            if (method()){
//                break;
//            }
//        }
//    }
//
//    // 同步方法
//    private synchronized boolean method(){
//        if (ticket <= 0) {
//            return true;
//        }
//        if (ticket > 0) {
//            System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
//        }
//        ticket--;
//        return false;
//    }
}

// main 方法
public class TicketTest {
    public static void main(String[] args) {
        // 任务对象
        Ticket ticket = new Ticket();

        // 线程对象 + 线程起名
        Thread t1 = new Thread(ticket,"窗口1");
        Thread t2 = new Thread(ticket,"窗口2");
        Thread t3 = new Thread(ticket,"窗口3");

        // 启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}

生产者消费者问题

  • 同步锁(synchronized) 解决线程访问共享数据的问题
// 共享数据
public class Resource {
    // 不能加 private  类名.属性名 访问不到
    static int num = 0; // 一开始桌子上没食物
    static final Object lock = new Object(); // 锁对象
}

// 生产者
public class Cooker implements Runnable {
    @Override
    public void run() {
        while (true) {
            synchronized (Resource.lock) {
                if (Resource.num == 0) {
                    System.out.println(Thread.currentThread().getName() + "开始做饭");
                    Resource.num = 1;
                    Resource.lock.notify(); // 唤醒阻塞进程
                } else {
                    try {
                        System.out.println(Thread.currentThread().getName() + "阻塞");
                        Resource.lock.wait(); // 阻塞进程
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
}


// 消费者
public class Consumer implements Runnable {
    @Override
    public void run() {
        while (true) {
            synchronized (Resource.lock) {
                if (Resource.num == 1) {
                    System.out.println(Thread.currentThread().getName() + "开始吃饭");
                    Resource.num = 0;
                    Resource.lock.notify(); // 唤醒阻塞进程
                } else {
                    try {
                        System.out.println(Thread.currentThread().getName() + "阻塞");
                        Resource.lock.wait(); // 阻塞进程
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
}

// main 方法
public class Test {
    public static void main(String[] args) {
        // 任务对象
        Cooker cooker = new Cooker();
        Consumer consumer = new Consumer();

        // 线程对象
        Thread t1 = new Thread(cooker, "厨师");
        Thread t2 = new Thread(consumer, "消费者");

        // 启动线程
        t1.start();
        t2.start();
    }
}

线程池

  • 通过Executors创建线程池对象
import java.util.concurrent.*;

public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 线程池对象  Executors + s
        ExecutorService pool = Executors.newFixedThreadPool(3);

        // 创建 Callable 类型的线程
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum = 0;
                for (int i = 1; i <= 10; i++) {
                    sum += i;
                }
                return sum;
            }
        };

        // 执行 Callable 类型的线程
        Future<Integer> future = pool.submit(task);

        System.out.println("Callable线程执行完毕,结果为:" + future.get());
    }
}

IO

复制文件(读文件 + 写文件)三种方法

  1. 一个字节一个字节读
  2. 每次读写指定大小的字节
  3. 采用缓冲区读取(大小自定义) 推荐!!!
// 方法一
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile {
    public static void main(String[] args) {
        // 创建字节流对象
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        long beginTime = 0;
        long endTime = 0;

        try {
            beginTime = System.currentTimeMillis();
            // 读字节流
            fileInputStream = new FileInputStream("day06/file/nuannuan.jpeg");
            // 写字节流
            fileOutputStream = new FileOutputStream("day06/file/nuanuan2.jpeg", true);

            // 读文件 写文件
            int data = 0;
            while ((data = fileInputStream.read()) != -1) {
                fileOutputStream.write(data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 释放资源  永远会执行 finally里的东西
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
                endTime = System.currentTimeMillis();
                System.out.println("耗时:" + (endTime - beginTime) + "ms");   // 9142ms
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


// 方法二
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFileBytes {
    public static void main(String[] args) {
        //1.创建输入输出流对象
        FileInputStream fis = null;
        FileOutputStream fos = null;
        long beginTime = 0;
        long endTime = 0;

        try {
            beginTime = System.currentTimeMillis();
            fis = new FileInputStream("day06/file/nuannuan.jpeg");
            fos = new FileOutputStream("day06/file/nuannuan1.jpeg");

            //2.读写数据
            byte[] bytes = new byte[1024]; // 每次读取1K
            int len;
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);   // 每次写读取到的长度
            }
            endTime = System.currentTimeMillis();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //3.关闭资源
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null) {
                    fos.close();
                }
                System.out.println("耗时:" + (endTime - beginTime) + "ms"); // 17ms
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

// 方法三
import java.io.*;

public class CopyFileBuffer {
    public static void main(String[] args) {

        // 1. 创建源和目标对象
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        long startTime = 0;
        long endTime = 0;

        // 2.读写文件
        try {
            startTime = System.currentTimeMillis();
            bis = new BufferedInputStream(new FileInputStream("day06/file/nuannuan.jpeg"), 1024 * 80);
            bos = new BufferedOutputStream(new FileOutputStream("day06/file/nuannuan1.jpeg"), 1024 * 80);

            int len = 0;
            while ((len = bis.read()) != -1) {
                bos.write(len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3. 释放资源
            try {
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
                endTime = System.currentTimeMillis();
                System.out.println("耗时:" + (endTime - startTime) + "ms"); //152ms
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

字符流 = 字节流 + 编码表读文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/943474.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c++---------流类

格式化输入&#xff08;cin的格式化&#xff09; 基本用法与控制符 在C中&#xff0c;std::cin用于从标准输入&#xff08;通常是键盘&#xff09;读取数据。它默认以空白字符&#xff08;空格、制表符、换行符&#xff09;为分隔符来读取不同的数据。例如&#xff0c;读取两个…

NIPS2014 | GAN: 生成对抗网络

Generative Adversarial Nets 摘要-Abstract引言-Introduction相关工作-Related Work对抗网络-Adversarial Nets理论结果-Theoretical Results实验-Experiments优势和不足-Advantages and disadvantages缺点优点 结论及未来工作-Conclusions and future work研究总结未来研究方…

MySQL 锁概述

1.锁的分类 根据不同的分类角度可将锁分为&#xff1a; 按是否共享分&#xff1a;S 锁、X 锁按粒度分&#xff1a;表级锁、行级锁、全局锁&#xff08;锁整个库&#xff09;、页锁&#xff08;锁数据页&#xff09;意向锁&#xff1a;意向 S 锁、意向 X 锁&#xff1a;都是表…

自然语言处理与知识图谱的融合与应用

目录 前言1. 知识图谱与自然语言处理的关系1.1 知识图谱的定义与特点1.2 自然语言处理的核心任务1.3 二者的互补性 2. NLP在知识图谱构建中的应用2.1 信息抽取2.1.1 实体识别2.1.2 关系抽取2.1.3 属性抽取 2.2 知识融合2.3 知识推理 3. NLP与知识图谱融合的实际应用3.1 智能问答…

模型工作流:自动化的模型内部三角面剔除

1. 关于自动减面 1.1 自动减面的重要性及现状 三维模型是游戏、三维家居设计、数字孪生、VR/AR等几乎所有三维软件的核心资产&#xff0c;模型的质量和性能从根本上决定了三维软件的画面效果和渲染性能。其中&#xff0c;模型减面工作是同时关乎质量和性能这两个要素的重要工…

大语言模型(LLM)中大数据的压缩存储及其重要性

在大型语言模型&#xff08;LLM&#xff09;中&#xff0c;KV Cache&#xff08;键值缓存&#xff09;的压缩方法及其重要性。 为什么要压缩KV Cache&#xff1f; 计算效率&#xff1a;在生成文本的过程中&#xff0c;每个生成的token都需要与之前所有的token的键值&#xff…

GitLab安装及使用

目录 一、安装 1.创建一个目录用来放rpm包 2.检查防火墙状态 3.安装下载好的rpm包 4.修改配置文件 5.重新加载配置 6.查看版本 7.查看服务器状态 8.重启服务器 9.输网址 二、GitLab的使用 1.创建空白项目 2.配置ssh 首先生成公钥&#xff1a; 查看公钥 把上面的…

从0开始在linux服务器上部署SpringBoot和Vue

目录 一、申请服务器的IP &#xff08;1&#xff09;阿里云申请IP &#xff08;2&#xff09;设置服务器的密码 &#xff08;3&#xff09;远程终端——MobaXterm 二、Docker &#xff08;1&#xff09;安装Docker &#xff08;2&#xff09;镜像加速 &#xff08;3&…

企业销售人员培训系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

智能家居实训室中,STC单片机驱动的“互联网+”智能家居系统设计

一、引言 随着经济的快速发展&#xff0c;人们对家居环境的智能化、网络化需求日益增强&#xff0c;智能家居的研究也因此受到了国内外相关机构的广泛关注。STC单片机凭借其卓越的性能和广泛的应用领域&#xff0c;成为了智能家居系统设计的优选方案。作为一种先进的微控制器&…

替代传统FTP传输,镭速大数据传输系统实现安全高效数据流转!

信息技术的快速进步让大数据成为了企业决策的关键支撑&#xff0c;但同时也带来了巨大的挑战。企业在运营过程中产生的数据量急剧增加&#xff0c;这对数据传输的速度、安全性和效率提出了更高的要求。然而&#xff0c;传统的FTP传输方式在处理大规模数据时显得力不从心&#x…

渗透Vulnhub-Solidstate靶机

本篇文章旨在为网络安全渗透测试行业靶机教学。通过阅读本文&#xff0c;读者将能够对渗透Vulnhub系列Solidstate靶机有定的了解 一、信息收集阶段 靶机官网&#xff1a;https://www.vulnhub.com/entry/solidstate-1%2C261/ 因为靶机为本地部署虚拟机网段&#xff0c;查看dhcp…

前端下载后端文件流,文件可以下载,但是打不开,显示“文件已损坏”的问题分析与解决方案

目录 场景还原 相关代码开发者工具 - 网络请求记录 问题排查 定位改bug 总结 场景还原 我在前端使用axios接收后端xlsx表格文件流并下载&#xff0c;xlsx文件能够下载成功&#xff0c;但是打开却显示文件无法打开 相关代码 请求API封装:Content–Type以及responseType经核…

什么样的LabVIEW控制算自动控制?

自动控制是指系统通过预先设计的算法和逻辑&#xff0c;在无人工干预的情况下对被控对象的状态进行实时监测、决策和调整&#xff0c;达到预期目标的过程。LabVIEW作为一种图形化编程工具&#xff0c;非常适合开发自动控制系统。那么&#xff0c;什么样的LabVIEW控制算作“自动…

【机器学习】探索机器学习与人工智能:驱动未来创新的关键技术

探索机器学习与人工智能&#xff1a;驱动未来创新的关键技术 前言&#xff1a;人工智能的核心技术深度学习&#xff1a;自然语言处理&#xff08;NLP&#xff09;&#xff1a;计算机视觉&#xff1a; 机器学习与人工智能的驱动创新医疗健康领域金融行业智能制造与工业互联网智慧…

在 Vue3 项目中实现计时器组件的使用(Vite+Vue3+Node+npm+Element-plus,附测试代码)

一、概述 记录时间 [2024-12-26] 本文讲述如何在 Vue3 项目中使用计时器组件。具体包括开发环境的配置&#xff0c;ViteVue 项目的创建&#xff0c;Element Plus 插件的使用&#xff0c;以及计时器组件的创建和使用。 想要直接实现计时器组件&#xff0c;查看文章的第四部分。…

图神经网络_图嵌入_Struc2Vec

0 背景 之前的node embedding方式&#xff0c;都是基于近邻关系&#xff0c;但是有些节点没有近邻&#xff0c;也有结构相似性。如图中的u、v节点。 struc2vec算法适用于捕获结构相似性。 1 相似度&#xff08;距离&#xff09;计算 1.1 公式 f k ( u , v ) f k − 1 ( u …

JZ31 栈的压入、弹出序列

题目来源&#xff1a;栈的压入、弹出序列_牛客题霸_牛客网 题目&#xff1a;如下 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序&#xf…

Android 蓝牙开发-传输数据

概述 传统蓝牙是通过建立REFCCOM sockect来进行通信的&#xff0c;类似于socket通信&#xff0c;一台设备需要开放服务器套接字并处于listen状态&#xff0c;而另一台设备使用服务器的MAC地址发起连接。连接建立后&#xff0c;服务器和客户端就都通过对BluetoothSocket进行读写…

Java圣诞树

目录 写在前面 技术需求 程序设计 代码分析 一、代码结构与主要功能概述 二、代码功能分解与分析 1. 类与常量定义 2. 绘制树的主逻辑 3. 彩色球的绘制 4. 动态效果的实现 5. 窗口初始化 三、关键特性与优点 四、总结 写在后面 写在前面 Java语言绘制精美圣诞树…