当前位置: 首页 > news >正文

初识Java 12-1 流

目录

Java 8对流的支持

流的创建

随机数流

int类型的区间范围

generate()

iterate()

流生成器

Arrays

正则表达式


本笔记参考自: 《On Java 中文版》


||| 流的概念:流是一个与任何特定的存储机制都没有关系的元素序列

        流与对象的成批处理有关。使用流的时候,我们会从一个管道Pipe,这一概念主要用于不同线程之间的通信)中抽取元素,并对它们进行操作。

    这些管道通常会被串联起来,形成这个流上的一个操作管线。

        流的一个核心优点是,它们能使我们的程序更小,也更好理解。而当配合流进行使用时,lambda表达式和方法引用能更好的发挥它们的作用。

【例子:以有序方式显示int数】

        在该例子中,需要按照有序方式显示随机选择的5~20范围内、不重复的int数。

import java.util.Random;public class Randoms {public static void main(String[] args) {new Random(47).ints(5, 20) // 生成一个ints类型的流,范围是5~20.distinct() // 中间流操作distinct():去除重复的值.limit(7) // 选择前7个值.sorted() // 进行排序.forEach(System.out::println); // 为每一个流元素执行括号中的操作}
}

        程序执行的结果如下:

        ints()方法会生成一个流,该方法有多个重载版本,其中两个元素的版本可以设置所生成值的上下界。

        注意:Randoms.java没有声明任何变量。流可以对有状态的系统进行建模,而不需要使用赋值或可变数据(在之后的例子中这种做法会经常见到)。

    上述这个例子展示了一种编程风格:声明式编程。我们说明想要完成什么(what),而不是指名怎么做(how)。

        上述例子的命令式编程形式如下,这种形式更难理解:

        这种形式需要定义3个变量,并且由于nextInt()无法确定下界,因此需要我们手动进行设定。这就体现了Randoms.java这种写法的优势:方便,并且表达清晰

        还可以这样区分上述这两个示例:

  • 外部迭代:像ImperativeRandoms.java这样显式地编写的迭代机制。
  • 内部迭代:像Randoms.java这样,我们看不见任何迭代机制。这种迭代产生的代码具有更好的可读性,并且更适用于多处理器。

        除此之外,流还有一个重要特性:惰性求值。这意味着它们只有在绝对必要时才会被求值(通常是在表达式的值被使用时)。这种延迟求值的特性,使得我们可以表示非常大的序列,而不用考虑内存问题。

Java 8对流的支持

        早期的Java并没有引入流的概念。这使得在后来,当Java的设计者想要引入流的概念时,面对的是一整套现有的库。若想要将流这个概念融入Java,就需要向接口中放入新的方法,这无疑会破坏原有的结构。

        Java 8引入的解决方案是接口中的默认(default)方法。使用它,Java的设计者们将流方法硬塞进了现有的类中(并且放入的操作还不少)。现在,可以将Java中的流操作分为三种类型:

  1. 创建流。
  2. 修改流元素(即中间操作)。
  3. 消费流元素(即终结操作),这种操作往往意味着收集一个流的元素(通常会将收集的元素放入一个集合中)。

流的创建

【例子:Stream.of()的使用例】

import java.util.stream.Stream;public class StreamOf {public static void main(String[] args) {Stream.of( // 在这里,构造器Bubble()只是用于生成一个普通的类new Bubble(1), new Bubble(2), new Bubble(3)).forEach(System.out::println);Stream.of("八百", "标兵", "奔", "北坡").forEach(System.out::print);System.out.println();Stream.of(3.14159, 2.718, 1.618).forEach(System.out::println);}
}

        程序执行的结果如下:

        通过使用Stream.of(),可以轻松地将一组条目变为一个流。

        另外,Collection也包含了一个stream()操作,通过它,可以生成一个基于Collection的流:

【例子:通过Collection生成一个流】

import java.util.*;public class CollectionToStream {public static void main(String[] args) {List<Bubble> bubbles = Arrays.asList(new Bubble(1), new Bubble(2), new Bubble(3));System.out.println(bubbles.stream() // 通过Collection生成一个流.mapToInt(b -> b.i) // 将对象流转变成一个包含Integer的IntStream.sum());Set<String> w = new HashSet<>(Arrays.asList("G F E D C B A".split(" ")));// map()操作会接受流中的每个元素,在其上应用括号中的操作来创建一个新的元素(这个新元素会继续顺着流传递下去)w.stream().map(x -> x + " ").forEach(System.out::print);System.out.println();Map<String, Double> m = new HashMap<>();m.put("pi", 3.14159);m.put("e", 2.718);m.put("phi", 1.618);m.entrySet().stream().map(e -> e.getKey() + ": " + e.getValue()).forEach(System.out::println);}
}

        程序执行的结果是:

        map()方法接受流中的每个元素,在其上应用一个操作来创建一个新的元素,然后将这个新元素沿着流继续传递下去。map()有许多不同的版本,比如mapToInt()等。

    所有集合类都有stream()方法。

        为了从Map集合中生成一个流,需要首先调用entrySet()来生成一个对象流(其中的每个对象都包含一个键和与其相关联的值)。

随机数流

        就像之前示例所示,Random类在Java 8时得到了增强,它获得了一组可以生成流的方法:

【例子:Random类的stream()方法使用(以int类型为例)】

import java.util.Random;
import java.util.stream.Stream;public class RandomGenerators {public static <T> void show(Stream<T> stream) {stream.limit(4).forEach(System.out::println);System.out.println("++++++++");}public static void main(String[] args) {Random rand = new Random(47);System.out.format("%n无参数时:%n");show(rand.ints().boxed()); // boxed()方法可以将基本类型转换为对应的包装器类型// 一个参数:控制流的大小System.out.format("%n一个参数时:%n");show(rand.ints(2).boxed());// 两个参数:控制上下边界System.out.format("%n两个参数时:%n");show(rand.ints(10, 20).boxed());// 三个参数:控制流的大小和边界System.out.format("%n三个参数时:%n");show(rand.ints(3, 3, 9).boxed());}
}

        程序执行的结果是:

        其他类型也有可以通过类型的方式创建流。

        在上述程序中出现了这样的语句:

public static <T> void show(Stream<T> stream) {

其中,类型参数T可以是任何东西,因此可以使用IntegerLong或者Double等)。另外,虽然Random类只会生成intdouble之类的基本类型的值。但boxed()流会自动将基本类型转换为其对应的包装器类型。

        使用Random,也可以创建一个可用于提供任何一组对象的Supplier

【例子:使用Random创建Supplier

        要求:读取以下文本文件(Cheese.dat),生成String对象。

Not much of a cheese shop really, is it?
Finest in the district, sir.
And what leads you to that conclusion?
Well, it's so clean.
It's certainly uncontaminated by cheese.

        编写程序,通过File类读取文本:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class RandomWords implements Supplier<String> {List<String> words = new ArrayList<>();Random rand = new Random(47);RandomWords(String fname) throws IOException { // throws:声明一个方法可能抛出的异常List<String> lines = Files.readAllLines(Paths.get(fname));// 使用的是外部迭代(可优化)for (String line : lines.subList(1, lines.size())) { // subList()方法用于去除第一行for (String word : line.split("[ .?,]+"))words.add(word.toLowerCase());}}@Overridepublic String get() {return words.get(rand.nextInt(words.size()));}@Overridepublic String toString() {return words.stream().collect(Collectors.joining(" "));}public static void main(String[] args) throws Exception {System.out.println(Stream.generate(new RandomWords("Cheese.dat")).limit(10).collect(Collectors.joining(" ")));}
}

        程序执行的结果是:

        上述语句出现中,split()方法的表达式变得更加复杂了。

line.split("[ .?,]+")

这条语句会在遇见 ①空格 或 ②方括号内存在的标点符号 时进行分隔。另外,方括号右边的+表示其前面出现的事物是可以重复出现的。

        在toString()main()中都出现了collect()操作,这一操作会根据参数将所有的流元素组合起来。当向collect()中传入一个Collectors.joining()时,得到的结果是一个String,它会根据joining()中的参数进行分隔。

    除上面演示的之外,还存在着许多的Collectors

        注意Stream.generate(),它可以接受任何的Supplier<T>,并生成一个由T类型的对象组成的流(这个流的长度可以看做无限长)


int类型的区间范围

        IntStream类提供了一个range()方法,可以生成一个由int值组成的流:

【例子:IntStream中的range()方法】

import static java.util.stream.IntStream.*;public class Ranges {public static void main(String[] args) {// 传统方式:生成一个int值组成的序列int result = 0;for (int i = 10; i < 20; i++)result += i;System.out.println(result);// for-in搭配一个区间范围result = 0;for (int i : range(10, 20).toArray())result += i;System.out.println(result);// 使用流System.out.println(range(10, 20).sum());}
}

        程序执行的结果如下:

        可以看出,使用流的第三种方法更加简便。

        另外,可以使用repeat()工具函数来取代简单的for循环:

【例子:repeat()方法及其使用例】

package onjava;import static java.util.stream.IntStream.*;public class Repeat {public static void repeat(int n, Runnable action) {range(0, n).forEach(i -> action.run());}
}

        使循环变得更加简洁:

import static onjava.Repeat.*;public class Looping {static void hi() {System.out.println("嗨!");}public static void main(String[] args) {repeat(3, ()->System.out.println("循环中..."));repeat(2, Looping::hi);}
}

        程序执行的结果是:


generate()

        再来看一个generate()方法的使用例:

【例子:generate()方法的使用例】

import java.util.Random;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Generator implements Supplier<String> {Random rand = new Random(47);char[] letters = "ABCDEFGHIJKLMN".toCharArray();@Overridepublic String get() {return "" + letters[rand.nextInt(letters.length)];}public static void main(String[] args) {String word = Stream.generate(new Generator()).limit(30) // 选择前30个值.collect(Collectors.joining()); // collect()在后台最终会调用Supplier<>的get()(可查看堆栈)System.out.println(word);}
}

        程序执行的结果是:

        在官方文档中,有关于generate()的说明:

这个方法会返回一个无限的、连续的并且没有顺序的流,其中的每个元素有Supplier生成。

        若想要创建一个由完全相同的对象组成的流,只需要将一个生成这些对象的lambda表达式传递给generate()即可:

import java.util.stream.Stream;public class Duplicator {public static void main(String[] args) {Stream.generate(() -> "duplicate").limit(3).forEach(System.out::println);}
}

        程序执行的结果是:

        Java会根据我们传入的lambda表达式(方法引用也是),在底层创建一个实现了目标接口的类的示例。因此generate()可以接受一个lambda表达式。

    复习:Supplier是一个函数式接口。

        接下来展示的是之前提到过的Bubble类,它包含了自己的静态生成器方法:

public class Bubble {public final int i;public Bubble(int n) {i = n;}@Overridepublic String toString() {return "Bubble(" + i + ")";}private static int count = 0;public static Bubble bubbler() {return new Bubble(count++);}
}

        在这里,bubbler()方法能够与Supplier<Bubble>接口相兼容,理由如下(参考讯飞星火):

  • bubbler()方法是静态的(可用于静态方法引用),并且返回类型是Bubble
  • 无参,与Supplier<Bubble>的无参构造器相匹配。
  • bubbler()的设计目的与Supplier<Bubble>的相符合,即提供一个无参数的工厂方法来生成特定类型的对象。

因此可以将该方法引用传递给Stream.generate()

import java.util.stream.Stream;public class Bubbles {public static void main(String[] args) {Stream.generate(Bubble::bubbler).limit(5).forEach(System.out::println);}
}

        程序执行的结果是:

        这是创建一个单独的工厂方法的一个替代方案。


iterate()

        Stream.iterate()的官方描述是这样的:

这个方法会从第一个种子(seed,即第一个参数)开始,将其传递给第二个参数所引用的方法。方法的结果会被添加到这个流上,并被保存下来作为下一次iterate()调用的第一个参数,以此类推。

    iterate()方法还有一个3参数的版本,多了一个用于筛选的谓词(Predicate)。

【例子:斐波那契数列】

import java.util.stream.Stream;public class Fibonacci {int x = 1;Stream<Integer> numbers() {return Stream.iterate(0, // 0被传递给i,作为i的初始值i -> { // i中储存的是return语句的返回值int result = x + i;x = i; // 需要使用一个x来保存另一个数值return result;});}public static void main(String[] args) {new Fibonacci().numbers().skip(20) // 跳过前20个数据.limit(10) // 然后再从中取出前10个.forEach(System.out::println);}
}

        程序执行的结果是:

        斐波那契数列将数列中的最后两个元素相加,生成下一个元素。由于iterate()只会记住结果(result),因此需要使用x来记住另一个元素。


流生成器

        在生成器(Builder)设计模式中,我们会创建一个生成器对象,为该对象提供多段构造信息,最终执行“生成”动作。Stream库提供了这样一个Builder

【例子:Builder的使用例】

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;public class FileToWordsBuilder {Stream.Builder<String> builder = Stream.builder();public FileToWordsBuilder(String filePath)throws Exception {Files.lines(Paths.get(filePath)).skip(1) // 跳过开头行.forEach(line -> {for (String w : line.split("[ .?,]+"))builder.add(w);});}Stream<String> stream() {return builder.build();}public static void main(String[] args) throws Exception {new FileToWordsBuilder("Cheese.dat").stream().limit(7).map(w -> w + " ").forEach(System.out::print);}
}

        程序执行的结果是:

        注意,在构造器添加文件中的单词时,它没有调用build()。这意味着,只要不调用stream()方法,就可以继续往builder对象中添加单词。

    可以加入一个标志来查看build()是否已经被调用,加入一个方法在可能的情况下继续添加单词。


Arrays

        Arrays类中同样包含了名为stream()的静态方法,可以将数组转换成流。

【例子:Arraysstream()

import java.util.Arrays;
import onjava.Operation;public class MetalWork2 {public static void main(String[] args) {Arrays.stream(new Operation[]{() -> Operation.show("Heat"),() -> Operation.show("Hammer"),() -> Operation.show("Twist"),() -> Operation.show("Anneal"),}).forEach(Operation::execute); // execute负责执行流中每个元素对应的操作}
}

        程序执行的结果是:

        上述例子中出现的Operation接口定义如下:

这是一个函数式接口,定义了show()方法和runOps()方法。

        new Operation[]表达式动态地创建了一个由Operation对象组成的类型化数组。forEach()操作会为数组中的每一个元素执行execute()。也就是说,在没有进入这条ForEach()操作之前,都可以继续往Operation[]中添加内容。

        使用stream()方法也可以生成IntStreamLongStreamDoubleStream

【例子:stream()方法生成其他Stream

import java.lang.reflect.Array;
import java.util.Arrays;public class ArrayStreams {public static void main(String[] args) {Arrays.stream(new double[]{3.14159, 2.718, 1.618}).forEach(n -> System.out.format("%f ", n));System.out.println();Arrays.stream(new int[]{1, 3, 5}).forEach(n -> System.out.format("%d ", n));System.out.println();Arrays.stream(new long[]{11, 22, 33, 44}).forEach(n -> System.out.format("%d ", n));System.out.println();// 选择一个子区间:Arrays.stream(new int[]{1, 3, 5, 7, 15, 28, 37}, 3, 6).forEach(n->System.out.format("%d ", n));System.out.println();}
}

        程序执行的结果是:

        最后出现的语句

(new int[]{1, 3, 5, 7, 15, 28, 37}, 3, 6)

多使用了两个额外的参数:第一个参数告诉stream()从数组哪个位置开始选择元素,第二个参数告诉stream()在哪里停下。


正则表达式

        Java 8向java.util.regex.Patern类中加入了一个新方法:splitAsStream()。这个新方法接受一个字符序列,并根据我们传入的公式将其分割为一个流。

    splitAsStream()有一个约束,其输入应该是一个CharSequence,因此我们不能将一个流传入splitAsStream()中。

【例子:利用正则表达式切割String

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class FileToWordsRegexp {private String all;public FileToWordsRegexp(String filepath)throws Exception {all = Files.lines(Paths.get(filepath)).skip(1) // 跳过第一行.collect(Collectors.joining(" "));}public Stream<String> stream() {return Pattern.compile("[ ,.?]+").splitAsStream(all);}public static void main(String[] args)throws Exception {FileToWordsRegexp fw = new FileToWordsRegexp("Cheese.dat");fw.stream().limit(7).map(w -> w + " ").forEach(System.out::print);System.out.println();fw.stream().skip(7).limit(2).map(w -> w + " ").forEach(System.out::print);System.out.println();}
}

        程序执行的结果是:

        构造器读取了文件中的信息,将其转入一个String中。在这里,我们可以多次回头调用stream(),并且每次都可以从保存的String中创建一个新的流。

        这个例子存在一个缺点:被读取的整个文件都要存储在内存中。这会导致流的两个优势(占据极少的内部存储,以及惰性求值)无法发挥其的作用。

相关文章:

初识Java 12-1 流

目录 Java 8对流的支持 流的创建 随机数流 int类型的区间范围 generate() iterate() 流生成器 Arrays 正则表达式 本笔记参考自&#xff1a; 《On Java 中文版》 ||| 流的概念&#xff1a;流是一个与任何特定的存储机制都没有关系的元素序列。 流与对象的成批处理有关…...

【软件工程_UML—StartUML作图工具】startUML怎么画interface接口

StartUML作图工具怎么画interface接口 初试为圆形 &#xff0c;点击该接口在右下角的设置中->Format->Stereotype Display->Label&#xff0c;即可切换到想要的样式 其他方式 在class diagram下&#xff0c;左侧有interface图标&#xff0c;先鼠标左键选择&#xff0…...

单片机之瑞萨RL78定时计数器

单片机之瑞萨RL78定时计数器 使用瑞萨RL78定时计数器的简单例程。这个例程使用定时器0来产生一个以秒为单位的定时器中断&#xff0c;并在中断服务程序中增加一个全局变量以跟踪中断的发生。 首先&#xff0c;我们需要了解RL78的定时器0是一个16位的定时器&#xff0c;它的时钟…...

手机号码格式校验:@Phone(自定义参数校验注解)

需求 新增接口 和 修改接口 中&#xff0c;手机号码的格式校验是普遍需要的。 在每个手机号码字段上添加正则表达式校验注解来实现校验&#xff0c;重复书写&#xff0c;容易出错&#xff1b;在不同的手机号码字段上&#xff0c;可能使用了不同的校验规则&#xff0c;无法有效…...

ORACLE Redo Log Buffer 重做日志缓冲区机制的设计

最近和朋友包括一些国产数据库的研发人员交流&#xff0c;很多程序员认为 Oracle 已经过时&#xff0c;开源数据库或者他们研发的国产数据库才代表数据库发展的未来。甚至在很多交流会议上拿出自家产品的某一个功能点和 Oracle 对比就觉得已经遥遥领先。 实际上数据库系统的发展…...

PWN Test_your_nc Write UP

目录 PWN 00 解题过程 总结归纳 PWN 01 解题过程 总结归纳 PWN 02 解题过程 总结归纳 PWN 03 解题过程 总结归纳 PWN 04 解题过程 总结归纳 CTF PWN 开始&#xff01; 冲就完了 PWN 00 解题过程 ssh远程链连接 ssh ctfshowpwn.challenge.ctf.show -p28151 输…...

Centos7配置firewalld防火墙规则

这里写自定义目录标题 欢迎使用Markdown编辑器一、简单介绍二、特点和功能2.1、区域&#xff08;Zone&#xff09;2.2、运行时和永久配置2.3、服务和端口2.4、动态更新2.5、连接跟踪2.6、D-Bus接口 三、设置规则3.1、启动防火墙服务3.2、新建防火墙规则的服务&#xff0c;添加端…...

【新版】系统架构设计师 - 未来信息综合技术

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 未来信息综合技术考点摘要信息物理系统CPS的体系架构CPS 的技术体系CPS应用场景 人工智能分类关键技术机器学习 机器人发展分类机器人4.0 边缘计算概念与特点边云协同安全应用场景 数字孪生关键技…...

CAD二次开发LineSegment2d

在C#的CAD二次开发中&#xff0c;LineSegment2d 是AutoCAD的.NET API中的一个类&#xff0c;用于表示二维空间中的线段。它包含了起点和终点的坐标信息&#xff0c;并提供了一些方法用于进行线段之间的计算和判断。 LineSegment2d 类具有以下常用属性和方法&#xff1a; Star…...

Linux shell编程学习笔记5:变量命名规则、变量类型、使用变量时要注意的事项

跟其他的高级开发语言一样&#xff0c;Linux Shell编程中使用的数据也需要保存在变量中。 Shell使用变量来控制其行为&#xff0c;并且可以通过更改变量值来更改Shell和其他程序的行为。 我们先来了解一下变量命令的规则、变量类型和使用变量时要注意的事项。 一、变量命名规…...

如何把word的页眉页脚改为图片

前言 亲戚A&#xff1a; 听说你是计算机专业&#xff1f; 沐风晓月&#xff1a; 是啊 亲戚A&#xff1a; 那正好&#xff0c;来看看我这个页眉怎么改成图片 沐风晓月&#xff1a; 一万匹马奔腾而过 亲戚B&#xff1a; 听说你是英语专业&#xff1f; 沐风晓月&#xff1a; 是啊…...

spring6-实现简易版IOC容器

手写简易版IOC容器 1、回顾Java反射2、实现Spring的IoC 我们都知道&#xff0c;Spring框架的IOC是基于Java反射机制实现的&#xff0c;下面我们先回顾一下java反射。 1、回顾Java反射 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所…...

Feign接口调用GET请求@RequestParam传参丢失

文章目录 问题现象排查解决GET加注解解决使用POST方式解决 时间戳传参失败 问题现象 项目使用的是Spring Cloud微服务&#xff0c;服务间调用使用的是Feign在一次服务调用时&#xff0c;发现GET传参丢失&#xff0c;没有传递过去任何参数加了RequestParam注解&#xff0c;发现…...

LeetCode每日一题 | 309.买卖股票的最佳时机含冷冻期

题目链接&#xff1a; 309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 算法图解&#xff1a; 解题代码&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();vector&…...

HTML的学习 Day02(列表、表格、表单)

文章目录 一、列表列表主要分为以下三种类型&#xff1a;1. 无序列表&#xff08;Unordered List&#xff09;&#xff1a;2. 有序列表&#xff08;Ordered List&#xff09;&#xff1a;将有序列表的数字改为字母或自定义内容li.../li 列表项标签中value属性&#xff0c;制定列…...

Android shape记录

之前一直觉得dataPath很好用&#xff0c;可以画各种矢量图。今天发现用shape画图也不错&#xff0c;记录一下自己用shape画的图。 一般使用shape就是定义形状、stroke边、solid内部、corners圆角等&#xff0c;代码 <?xml version "1.0" encoding "utf-8&q…...

WSL2和ubuntu的安装过程

目录 1.WSL2的安装 2.Ubuntu的安装 3.安装完成后的打开方式 1.WSL2的安装 按下WINX键&#xff0c;选择Windows PowerShell (管理员) 1.1执行以下命令&#xff0c;该命令的作用是&#xff1a;启用适用于 Linux 的 Windows 子系统 dism.exe /online /enable-feature /featur…...

力扣第150题 逆波兰表达式求值 stack c++

题目 150. 逆波兰表达式求值 中等 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 、-、* 和 / 。每个操作数&#xff08;运算对象&#xff09;都…...

三、飞行和射击

目录 1.飞行的实现 2.限制玩家视角 3.射击的实现 4.附录 1.飞行的实现 &#xff08;1&#xff09;在Player预制体上挂载Configuration Joint组件&#xff0c;并修改其Y Drive属性 &#xff08;2&#xff09; 修改PlayerInput.cs和PlayerController.cs以实现飞行 PlayerIn…...

GitHub与GitHubDesktop的使用

1、介绍 见天来学习使用GitHub与GitHubDesktop。 学习前先来介绍一下什么是GitHub。 GitHub是一个基于Git的代码托管平台和开发者社区。它提供了一个Web界面&#xff0c;让开发者能够轻松地托管、共享和管理他们的软件项目。 在GitHub上&#xff0c;开发者可以创建自己的代…...

AIGC 微调的方法

AIGC 的微调方法可以分为以下步骤&#xff1a; 数据准备&#xff1a;收集尽可能多的数据&#xff0c;包括输入和输出数据&#xff0c;并将其划分为训练集、验证集和测试集。 模型选择&#xff1a;选择合适的模型结构&#xff0c;例如多层感知器&#xff08;MLP&#xff09;、卷…...

gcc编译webrtc x64

gcc使用Ubuntu系统已经有的gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 1、下载离线版webrtc&#xff08;也可以翻墙下载webrtc&#xff09; 百度云链接: 链接: https://pan.baidu.com/s/1oHVz9bxXlW3Q6uO996c5XA 提取码: ojbs 2、下载gn https://github.com/timnieder…...

uni-app 实现凸起的 tabbar 底部导航栏

效果图 在 pages.json 中设置隐藏自带的 tabbar 导航栏 "custom": true, // 开启自定义tabBar(不填每次原来的tabbar在重新加载时都回闪现) 新建一个 custom-tabbar.vue 自定义组件页面 custom-tabbar.vue <!-- 自定义底部导航栏 --> <template><v…...

中国1km土壤特征数据集(2010年)

简介&#xff1a; 中国1km土壤特征数据集&#xff08;2010&#xff09;是基于第二次全国土壤调查的中国1:1000000比例尺土壤图和8595个土壤剖面图&#xff0c;以及美国农业部&#xff08;USDA&#xff09;中国区域土地和气候模拟标准&#xff0c;开发了一个多层土壤粒度分布数…...

计算机网络笔记 第二章 物理层

2.1 物理层概述 物理层要实现的功能 物理层接口特性 机械特性 形状和尺寸引脚数目和排列固定和锁定装置 电气特性 信号电压的范围阻抗匹配的情况传输速率距离限制 功能特性 -规定接口电缆的各条信号线的作用 过程特性 规定在信号线上传输比特流的一组操作过程&#xff0…...

使用CreateProcess崩溃:处未处理的异常: 0xC0000005: 写入位置 0x00415652 时发生访问冲突

问题代码 if (!CreateProcess(NULL,L"pela.exe",NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)){return 0;}如果CreateProcess的第二个参数字符串是常量或者是储存在堆中的就会被写保护&#xff0c;崩溃。如果字符串定义到栈或者全局变量就不存在此问题了。 正确的…...

Java 华为真题-出租车计费

需求 程序员小明打了一辆出租车去上班。出于职业敏感&#xff0c;他注意到这辆出租车的计费表有点问题&#xff0c;总是偏大。 出租车司机解释说他不喜欢数字4&#xff0c;所以改装了计费表&#xff0c;任何数字位置遇到数字4就直接跳过&#xff0c;其余功能都正常。 比如&…...

开源layui前端框架 收款码生成系统源码 多合一收款码生成源码 带50多套UI模板

Layui前端的多合一收款码在线生成系统源码_附多套前端UI模板。 卡特三合一收款码生成系统源码&#xff0c;和收款啦采用一样的原理。 内部多达50多套模板&#xff0c;前端跟付款界面都特别好看。 识别收款码之后会自动加密&#xff0c;非常安全。 一样没有后台&#xff0c;一样…...

微服务moleculer01

1.官网地址&#xff1a; Moleculer - Progressive microservices framework for Node.js 2. github代码地址&#xff1a; GitHub - moleculerjs/moleculer: :rocket: Progressive microservices framework for Node.js Moleculer是基于Node.js的一款快速、多功能的微服务框…...

C++中将指针传递给函数

C中将指针传递给函数 指针是一种将内存空间传递给函数的有效方式&#xff0c;其中可包含函数完成其工作所需的数据&#xff0c;也可包含操作结果。将指针作为函数参数时&#xff0c;确保函数只能修改您希望它修改的参数很重要。例如&#xff0c;如果函数根据以指针方式传入的半…...

武汉网站 互动/百度首页登录官网

绪论 1 研究的意义及必要性燃气轮机是典型的动力设备&#xff0c;被广泛地应用于电力、能源、交通及军事等关系国计民生的重要部门。因此&#xff0c;研究如何提高燃气轮机使用寿命及可靠性&#xff0c;减少事故发生&#xff0c;以充分提高其经济性及安全性系数&#xff0c;无…...

网站上的幻灯片如何做/seo优化怎么做

一. BluetoothClass简介 1. 继承关系 public final class BluetoothClass extends Object implements Parcelable 该类是final类, 不能被继承, 没有子类; 该类继承了Object类, 实现了Parcelable接口; Parcelable接口 : Java中的序列化方法 : 在Java中序列化有两种方法, 一种是…...

织梦mip网站改造/推广计划方案

链表排序 Sort List &#xff3b;抄题&#xff3d;&#xff1a; &#xff3b;思维问题&#xff3d;&#xff1a; &#xff3b;一句话思路&#xff3d;&#xff1a; &#xff3b;输入量&#xff3d;&#xff1a;空&#xff1a; 正常情况&#xff1a;特大&#xff1a;特小&#…...

wordpress对应国家语言/跨境电商seo

以下資料都來自網上,有不正確之處敬請諒解. http://blog.sina.com.cn/s/blog_661beca00100snex.html jQuery在客户端操作Table学习&#xff1a;不过有很多很多的不足&#xff0c;还需要学习掌握。 <style type"text/css"> .hover { back…...

贵州企业官网建设/优化公司怎么优化网站的

对于那些不能在Win 7上正常运行的程序&#xff0c;我的选择就是把这些程序装在XP Mode中。现在&#xff0c;XP Mode可以不需要硬件虚拟化 (例如 Intel的VT)的支持了。 from Windows 7 XP Mode FAQ XP Mode可以单独下载...

有没有让人做问卷的网站/站长工具关键词挖掘

得先知道后台接口给ajax访问&#xff08;接口URl和传入接口的参数及参数类型&#xff09;&#xff0c;知道访问之后返回的数据类型&#xff0c;有哪些数据。 选择异步请求的方式&#xff0c;常用的有三种&#xff0c;如$.ajax()、$.post()、$.get()。 其中$.ajax允许get/post两…...