Stream和方法引用

1. Stream流

1.1. Stream流引入
 Stream流完全不是I/O流,按照流水线处理方式来考虑代码中的思想。JDK1.8 之后,我们拥有了Lambda表达式,让代码的中心偏向解决实际问题,直到重点,可以提高效率。Stream流中使用了大量Lambda表达式,利用Lambda操作方式,提供开发效率
1.2 传统遍历方式和Stream类处理方式对比
import java.util.ArrayList;/*** 操作集合处理集合*      操作过程中创建了多个ArrayList,但是这些ArrayList都是过客,*      不涉及到程序的核心,这里会导致资源的浪费。*/
public class Demo2 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("大肠刺身");list.add("酱牛肉");list.add("羊肉串");list.add("烤羊排");list.add("羊肉汤");list.add("驴肉火烧");// 第一步: 对List进行过程,找出list中保存元素带有肉的,保存到另一个集合中ArrayList<String> list1 = new ArrayList<>();for (String s : list) {if (s.contains("肉")) {list1.add(s);}}// 第二步: 找出菜名长度==3的,保存到另一个集合中ArrayList<String> list2 = new ArrayList<>();for (String s : list1) {if (3 == s.length()) {list2.add(s);}}// 第三步:遍历展示对应的数据for (String s : list2) {System.out.println(s);}}
}
import java.util.ArrayList;/*** 操作集合处理集合*      采用Stream流方式**/
public class Demo2 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("宫保鸡丁");list.add("酱牛肉");list.add("羊肉串");list.add("烤羊排");list.add("羊肉汤");list.add("驴肉火烧");/*采用Stream流方式来处理直观角度可以发现,这里Stream流处理方式可以简化代码逻辑,更侧重于操作的重点第一步: 对List进行过程,找出list中保存元素带有肉的,第二步: 找出菜名长度==3的第三步:遍历展示对应的数据*/list.stream().filter(s->s.contains("肉")).filter(s -> 3 == s.length()).forEach(s -> System.out.println(s));}
}
1.3 Stream流对应的思想
请你忘掉原先的IO流思想
流水线:原材料从头到尾只会占用一份空间,中间的过程中不会占用空间。最后生成一个结果。
Stream流有一些特征:1. 带有很多Stream流操作的方法, filter,limit,map,sorted,skip...这些方法大多是都会使用到函数式接口,有lambda表达式2. 整个Stream流模型操作过程中,只有执行到count,foreach这些方法,操作真正的执行中的模型,如果不存在结果导向,中间的所有操作是无效的,这里得益于Lambda表达式的延后性3. Stream流是存在一定的管道性 Pipelining 流水线
1.4 获取Stream流
java.util.stream.Stream<T> JDK1.8的新特征1. 所有的Collection<T>集合都有对应的Stream();2. 可以通过Stream类中的static Stream of()获取static Stream<T> of(T... t);static Stream<T> of(T t);
import java.util.*;
import java.util.stream.Stream;/*** Stream流获取方式*      1. Collection集合*      2. Map双边队列*      3. 数组**/
public class Demo1 {public static void main(String[] args) {// List接口获取对应的Stream流类对象List<String> list = new ArrayList<>();// 根据list保存元素的类型来约束对应的Stream流对象操作所需类型Stream<String> stream = list.stream();// 通过Set集合获取对应Stream流对象HashSet<String> set1 = new HashSet<>();Stream<String> stream1 = set1.stream();HashMap<String, String> map = new HashMap<>();// Map双边队列中所有键对应的Set集合Set<String> keySet = map.keySet();Stream<String> stream2 = keySet.stream();// Map双边队列中所有value对应的Collection集合Collection<String> values = map.values();Stream<String> stream3 = values.stream();// map中有一个方法,可以获取所有键值对类型的Set集合// Entry ==> 键值对,是Map接口的一个成员接口Set<Map.Entry<String, String>> entrySet = map.entrySet();// 获取Map键值对集合的Stream流对象Stream<Map.Entry<String, String>> stream4 = entrySet.stream();// 使用不定长参数获取对应的Stream流对象// Stream类内的静态方法of,更多的是用于数组操作提供Stream流对象Stream<String> stringStream = Stream.of("酱牛肉", "羊肉抓饭", "羊肉汤", "羊蝎子");String[] arr = {"河南建业", "广州恒大淘宝", "北京国安", "山东鲁能", "广州富力"};Stream<String> arrStream = Stream.of(arr);// 不建议这样使用!!!ArrayList<String> list1 = new ArrayList<>();Stream<ArrayList<String>> list11 = Stream.of(list1);}
}
1.5 Stream常用方法
延迟方法:返回值类型依然是Stream接口本身,并没有影响我们操作真正的资源允许链式操作,例如filter(XXX).limit(XXX).sorted(XXX).
终结方法:返回值类型不是Stream接口本身,要么处理数据,要么返回其他类型数据,并且不再支持Stream流对象链式操作,count,foreach
1.5.1 foreach方法【终结方法】
void foreach(Consumer<? super T> action);
/*
终结方法:需要一个Consumer接口进行操作处理,消耗一个数据Consumer接口是一个【函数式接口】那就可以使用Lambda表达式Consumer接口中方法是void accept(T t);
*/
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;/*** Stream流foreach方法使用**/
public class Demo1 {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("蛋炒饭");list.add("大肠刺身");list.add("手撕包菜");list.add("鲱鱼罐头");// 得到List对应的Stream流对象Stream<String> stream = list.stream();/*Stream<String> Stream流,这里操作的是String类型匿名内部类的匿名对象作为方法的参数,曾经多么厉害,现在是有点low*/stream.forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}});// 这里需要的参数是Consumer函数式接口,完成可以使用Lambda表达式完成stream.forEach(string -> System.out.println(string));}
}
1.5.2 filter方法
Stream<T> filter(Predicate<? super T> condition);
/*filter是过滤方式,需要的参数是Predicate接口,Predicate是一个函数式接口,可以直接使用Lambda表达运行。这里返回值类型是Stream类对象,是经过过滤之后的Stream类型,可以进行链式操作Predicate接口中需要实现的方法boolean test(T t);
*/
import java.util.ArrayList;
import java.util.stream.Stream;/*** Stream流对象filter方法演示**/
public class Demo2 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("擀面皮");list.add("肉夹馍");list.add("冰峰");list.add("水盆羊肉");Stream<String> stringStream = list.stream().filter(s -> s.length() >= 3);stringStream.forEach(System.out::println);Stream<String> stringStream1 = stringStream.filter(s -> 4 == s.length());stringStream1.forEach(System.out::println);/*Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closedat java.util.stream.AbstractPipeline.<init>(AbstractPipeline.java:203)at java.util.stream.ReferencePipeline.<init>(ReferencePipeline.java:94)at java.util.stream.ReferencePipeline$StatelessOp.<init>(ReferencePipeline.java:618)at java.util.stream.ReferencePipeline$2.<init>(ReferencePipeline.java:163)at java.util.stream.ReferencePipeline.filter(ReferencePipeline.java:162)at com.qfedu.c_streamfunction.Demo2.main(Demo2.java:23)*/}
}
1.5.3 map方法
<R> Stream<R> map(Function<? super T, ? super R> fun);
/*
类型转换操作,得到的一个转换之后数据类型的Stream流对象
这里需要的参数是Functtion函数式接口,R apply(T t);T类型的数据转换成R类型数据
*/
import java.util.ArrayList;
import java.util.stream.Stream;/*** Stream流 map映射方法演示**/
public class Demo3 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("1,dr7,16");list.add("2,ch,66");list.add("3,wf,46");list.add("4,wy,36");list.add("5,wsy,56");list.add("6,wl,26");System.out.println(list);Stream<Person> personStream = list.stream().map(s -> {String[] split = s.split(",");Person person = new Person();person.setId(Integer.parseInt(split[0]));person.setName(split[1]);person.setAge(Integer.parseInt(split[2]));return person;});personStream.forEach(System.out::println);}
}
1.5.4 count方法【终结方法】
long count();
/*
返回当前Stream流对象中有多少个元素
类似有Collection接口下的size(). String的length();
【终结方法】一旦执行Stream流对象被关闭
*/
package com.qfedu.c_streamfunction;import java.util.ArrayList;/*** Stream流对象 count方法演示【终结方法】**/
public class Demo4 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("裹凉皮");list.add("肉夹馍");list.add("冰峰");list.add("水盆羊肉");// 当前Stream流对象中有多少个元素,终结方法long count = list.stream().filter(s -> s.length() >= 3).count();System.out.println(count);}
}
1.5.5 limit方法
Stream<T> limit(long maxSize);
/*
对于当前Stream流对象操作的数据进行限制操作,限制个数到maxSize
例如:Stream流中保存的有10个元素,limit 5 ==> 前五个元素
*/
import java.util.ArrayList;
import java.util.stream.Stream;/*** Stream流对象 limit方法**/
public class Demo5 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("特斯拉");list.add("奔驰G");list.add("雅阁");list.add("比亚迪");list.add("长安");list.add("雅迪");Stream<String> stream = list.stream();// @throws IllegalArgumentException if {@code maxSize} is negativestream.limit(5).forEach(System.out::println);}
}
1.5.6 skip方法
Stream<T> skip(long n);
/*
返回值依然是一个Stream流对象,这里跳过当前Stream流对象前n个元素
*/
import java.util.ArrayList;/*** Stream流对象 skip方法**/
public class Demo6 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("特斯拉");list.add("奔驰G");list.add("雅阁");list.add("比亚迪");list.add("长安");list.add("雅迪");list.stream().skip(2).forEach(System.out::println);}
}
1.5.7 concat方法
static Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
/*
拼接两个Stream流对象,是一个静态方法,得到新的Stream流对象
*/
import java.util.ArrayList;
import java.util.stream.Stream;/*** Stream流 静态成员方法 concat方法**/
public class Demo7 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("红旗");list.add("领克");list.add("吉利");list.add("比亚迪");list.add("长安");list.add("五菱宏光");ArrayList<String> list1 = new ArrayList<>();list1.add("陆巡");list1.add("高R");list1.add("RS7");list1.add("s4");list1.add("霸道");list1.add("道奇");// 获取到两个Stream流,其中保存的数据类型都是String类型Stream<String> stream = list.stream();Stream<String> stream1 = list1.stream();Stream<String> concat = Stream.concat(stream, stream1);concat.forEach(System.out::println);}
}
1.5.8 原始操作方式和Stream流方式对比
1. 一个String类型的字符串集合,"1,dr7,16"
2. 过滤没有5的数据
3. 跳过前三个数据
4. 限制得到前5个数据
5. 两个String类型集合字符串合并
6. 转换成Person类型
7. 展示数据
import java.util.ArrayList;/*** 采用原始的List集合方式操作*   1. 一个String类型的字符串集合,"1,骚磊,16"*   2. 过滤没有5的数据*   3. 跳过前三个数据*   4. 限制得到前5个数据*   5. 两个String类型集合字符串合并*   6. 转换成Person类型*   7. 展示数据**   太浪费资源,浪费时间!!!*/
public class Demo8 {public static void main(String[] args) {//  1. 一个String类型的字符串集合,"1,骚磊,16"ArrayList<String> list1 = new ArrayList<>();list.add("1,dr7,16");list.add("2,ch,66");list.add("3,wf,46");list.add("4,wy,36");list.add("5,wsy,56");list.add("6,wl,26");list.add("1,dr7,16");list.add("2,ch,66");list.add("3,wf,46");list.add("4,wy,36");list.add("5,wsy,56");list.add("6,wl,26");// 2. 过滤没有5的数据ArrayList<String> list2 = new ArrayList<>();for (String s : list1) {if (s.contains("5")) {list2.add(s);}}System.out.println(list2);// 3. 跳过前三个数据ArrayList<String> list3 = new ArrayList<>();for (int i = 3; i < list2.size(); i++) {list3.add(list2.get(i));}System.out.println(list3);// 4. 限制得到前5个数据ArrayList<String> list4 = new ArrayList<>();for (int i = 0; i < 5; i++) {list4.add(list3.get(i));}// 5. 两个String类型集合字符串合并ArrayList<String> list5 = new ArrayList<>();list.add("1,dr7,16");list.add("2,ch,66");list.add("3,wf,46");list.add("4,wy,36");list.add("5,wsy,56");list.add("6,wl,26");list4.addAll(list5);// 6. 转换成Person类型ArrayList<Person> list6 = new ArrayList<>();for (String s : list4) {String[] split = s.split(",");Person person = new Person();person.setId(Integer.parseInt(split[0]));person.setName(split[1]);person.setAge(Integer.parseInt(split[2]));list6.add(person);}// 7. 展示数据for (Person person : list6) {System.out.println(person);}}
}
import java.util.ArrayList;
import java.util.stream.Stream;/*** 采用原始的Stream流对象思想方式操作*   1. 一个String类型的字符串集合,"1,dr7,16"*   2. 过滤没有5的数据*   3. 跳过前三个数据*   4. 限制得到前5个数据*   5. 两个String类型集合字符串合并*   6. 转换成Person类型*   7. 展示数据*/
public class Demo9 {public static void main(String[] args) {ArrayList<String> list1 = new ArrayList<>();list.add("1,dr7,16");list.add("2,ch,66");list.add("3,wf,46");list.add("4,wy,36");list.add("5,wsy,56");list.add("6,wl,26");list.add("1,dr7,16");list.add("2,ch,66");list.add("3,wf,46");list.add("4,wy,36");list.add("5,wsy,56");list.add("6,wl,26");ArrayList<String> list2 = new ArrayList<>();list.add("1,dr7,16");list.add("2,ch,66");list.add("3,wf,46");list.add("4,wy,36");list.add("5,wsy,56");Stream<String> stream = list1.stream();Stream<String> limit = stream.filter(s -> s.contains("5")).skip(3).limit(5);Stream.concat(limit, list2.stream()).map(s -> {String[] split = s.split(",");Person person = new Person();person.setId(Integer.parseInt(split[0]));person.setName(split[1]);person.setAge(Integer.parseInt(split[2]));return person;}).forEach(System.out::println);}
}

2. 方法引用

2.1 Lambda冗余问题以及方法引用初识
package com.qfedu.d_methodreference;/*** 函数式接口** @author Anonymous*/
@FunctionalInterface
interface PrintMethod {void print(String str);
}/*** Lambda冗余问题**/
public class Demo1 {public static void main(String[] args) {/*使用Lambda表达式来展示字符串IDEA有一个提示,这里可以继续优化目标:testPrint方法,需要将String str交给 PrintMethod进行处理PrintMethod处理的方式是System.out.printlnPrintMethod是一个函数式接口,可以使用Lambda表达式完成代码但是貌似和这个接口,这里Lambda不够接近目标明确:1. 我要用System.out对象2. 需要使用println方法3. 需要处理的数据是明确的*/testPrint("郑州加油!!!", str -> System.out.println(str));// 利用方法引用来处理当前代码/*调用对象:System.out执行方法:println方法需要处理的数据(可推导,可省略)"中国加油!!!祖国万岁!!!"::Java中【方法引用】使用的运算符,标记*/testPrint("中国加油!!!祖国万岁!!!", System.out::println);}/*** 该方法是一个使用函数式接口作为方法参数的一个方法** @param str String类型的字符串* @param pm  PrintMethod函数式接口*/public static void testPrint(String str, PrintMethod pm) {pm.print(str);}
}
2.2 方法引用小要求
 testPrint("郑州加油!!!", str -> System.out.println(str));testPrint("郑州加油!!!", System.out::println);1. 明确对象对象 ==> 调用者类对象,类名,super,this,构造方法,数组构造方法2. 明确的执行方法该方法只有名字不需要显式出现参数3. 需要处理的数据【联想,推导,省略】4. :: 方法引用格式
2.3 通过类对象来执行方法引用
1. 明确对象类对象
2. 明确执行的方法自定义
3. 处理的数据简单要求为String类型
package com.qfedu.e_objectmethodreference;/*** 函数式接口*      明确约束方法*          方法类型是*              参数是String类型参数*              没有返回值*/
@FunctionalInterface
public interface Printable {void method(String str);
}
package com.qfedu.e_objectmethodreference;/*** 自定义类*/
public class ObjectMethodReference {/*** ObjectMethodReference类内的【成员方法】*     1. 参数是String类型*     2. 没有返回值* @param str 参数*/public void print(String str) {System.out.println(str.toLowerCase());}/*** ObjectMethodReference类内的【成员方法】*     1. 参数是String类型*     2. 没有返回值* @param str 参数*/public void printSubstring(String str) {System.out.println(str.substring(3));}public void saolei() {System.out.println("无参数方法");}
}
``````java/*** 类对象使用方法引用展示**/
public class Demo2 {public static void main(String[] args) {/*test方法需要使用一个Printable接口,执行对应的print方法这里需要引用ObjectMethodReference类对象对应的print方法,该方法有展示能力*/ObjectMethodReference obj = new ObjectMethodReference();/*执行的对象:ObjectMethodReference的类对象明确执行的方法:print方法执行的目标:"ABCDE" 可省略,可推导*/test(obj::printSubstring);}/**** @param printable 函数式接口,约束的是方法类型*/public static void test(Printable printable) {printable.method("ABCDE");}
}```##### 2.4 通过类名来执行方法引用```javaimport java.util.List;/*** 函数式接口*/
@FunctionalInterface
public interface PrintList {/*** 方法参数为List集合* 没有返回值* @param list List集合*/void print(List<?> list);
}
``````java
import java.util.List;/*** 通过列明调用的静态方法,演示类*/
public class ClassMethodReference {/*** 该方法符合要求* 没有返回值* @param list list集合*/public static void showListInfo(List<?> list) {for (Object o : list) {System.out.println(o);}}
}
``````java
import java.util.ArrayList;/*** 通过类名来执行方法引用**/
public class Demo3 {public static void main(String[] args) {/*明确调用对象当前方法是一个静态成员方法,需要通过类名调用明确调用方法showListInfo明确的数据ArrayList<String> list = new ArrayList<>();可省略,可推导*/testClass(ClassMethodReference::showListInfo);/*Lambda表达式*/testClass(list -> {for (Object o : list) {System.out.println(o);}});}/*** 利用了一个函数式接口作为方法的参数** @param printList 函数式接口*/public static void testClass(PrintList printList) {ArrayList<String> list = new ArrayList<>();list.add("BMW");list.add("Audi");printList.print(list);}}```##### 2.5 通过super关键字执行方法引用```java
/*** */
public interface SaySomeThing {void say();
}
``````java/*** */
public class Father {public void sayHello() {System.out.println("你好 Java");}
}
``````javaimport java.util.Scanner;/****/
public class Son extends Father {public static void main(String[] args) {//lambdatestSay(() -> System.out.println("你好"));new Son().sonMethod();}/*** 这里的参数是一个函数式接口,这里需要提供给一个符合要求的方法* @param sst 函数式接口参数*/public static void testSay(SaySomeThing sst) {sst.say();}public void sonMethod() {/*父类中有一个无参数无返回值的sayHello满足当前SaySomeThing函数式接口,方法要求执行的对象super关键字,因为该方法在父类内执行的方法:sayHello无需参数*/testSay(super::sayHello);}
}
```##### 2.6 通过this关键字执行方法引用```java/*** */
public interface ORM {/*** int ==> String* @param i int类型* @return String类型*/String toStringType(int i);
}
``````java/*** */
public class ThisDemo {public void test() {String s = testThis(i -> i + ":");System.out.println(s);/*调用方法的对象this执行的方法:turn方法处理的数据10 (可省略,可联想)*/String s1 = testThis(this::turn);}public String turn(int i) {return i + ":字符串";}public static String testThis(ORM orm) {return orm.toStringType(10);}public static void main(String[] args) {new ThisDemo().test();}
}
```

Stream和方法引用相关推荐

  1. Java基础 Stream流方法引用异常文件

    Stream流 引例 需求:按照下面要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素 1. 把所有以"曹"开头的元素存储到新集合中 2. 把曹开头,长度为3的元素存储到新 ...

  2. Stream流方法引用

    一.对象存在,方法也存在,双冒号引用 1.方法引用的概念: 使用实例: 1.1先定义i一个函数式接口: 1.2定义一个入参参数列表有函数式接口的方法: 1.3调用这个入参有函数式接口的方法: lamb ...

  3. java(九)-方法引用, Stream流,File类 , 递归 ,字节流

    day09[方法引用.Lambda表达式.Stream流] 今日目标 线程状态 等待与唤醒 Lambda表达式 Stream流 教学目标 能够说出线程6个状态的名称 能够理解等待唤醒案例 能够掌握La ...

  4. 15.方法引用, Stream流,File类 , 递归 ,字节流

    JavaSE高级 Lambda表达式.方法引用.Stream流.File类 第一章 JDK8新特性 JDK新特性: Lambda 表达式 默认方法[已学习过] Stream API 方法引用 Base ...

  5. Sream流、方法引用

    目录 Stream流 方法引用 Stream流 Stream(流)是一个来自数据源的元素队列 元素是特定类型的对象,形成一个队列. Java中的Stream并不会存储元素,而是按需计算 数据源 流的来 ...

  6. 学习笔记之-java8的新特性-函数式接口,lambda表达式,方法引用,Stream API,Optional类

    1.Lambda表达式 用匿名内部类的方法去创建多线程1.new Thread2.参数传递new Runnable3.重写run方法4.在run方法中去设置线程任务5.调用start问题:我们最终目标 ...

  7. 【Java】Stream流和方法引用

    1 Stream流 1.1 Stream流优化过滤集合 传统方式 用一个循环过滤姓张的人 用一个循环过滤名字长度大于2的人 public static void main(String[] args) ...

  8. 【Java从入门到头秃专栏 7】语法篇(六) :Lambda表达式(->) 方法引用(::) stream流

    目录 1 Lambda表达式( -> ) ​ 2 方法引用( :: ) 3 Stream流 接下来介绍的三种语法叫:Lambda表达式 方法引用 stream流,这三种语法的使用要有特定条件,在 ...

  9. jdk8新特性(接口新特性、lambda表达式、方法引用、函数式接口、Stream流)和单例设计模式

    1.单例设计模式 1.概念: 设计模式:使用固有的流程或方式设计出来的类接口.枚举等元素 2.设计原则: 1.私有化构造方法[private.protected] 2.类中创建最终对象[唯一不能被赋值 ...

最新文章

  1. AlphaGo的原理
  2. 浅谈 Kubernetes Scheduling-Framework 插件的实现
  3. Linux的实际操作:文件目录类的实用指令 (显示路径pwd 显示文件ls 更改目录cd)
  4. 汉字和utf编码转换
  5. javadocx转换成html_使用Java将Word转为Html或txt[转]
  6. 《机器学习实战》学习总结(二)决策树算法原理
  7. 众说纷“云”,看生态驱动工业物联网落地
  8. 【渝粤教育】国家开放大学2018年春季 8618-22T燃气行业规范 参考试题
  9. 高斯烟羽模型matlab程序,高斯烟羽模型的改进及在危化品泄漏事故模拟中的应用...
  10. Python网络爬虫案例
  11. python dlib caffe人脸相似度_人脸检测学习笔记(数据集-DLIB人脸检测原理-DLIBOpenCV人脸检测方法及对比)...
  12. kettle 同步Oracle 与 Postgres
  13. A study finds nearly half of jobs are vulnerable to automation
  14. 数字化时代-15:从商品交换过程解剖淘宝电商
  15. 产品经济学之产品定价策略——老吴说产品
  16. vite以及webpack(@vue/cli 5.x) vue3 alias别名配置
  17. Java毕业设计-超市综合管理信息系统
  18. 关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript
  19. 1718: 身体质量指数
  20. 单表代替和多表代替密码体系

热门文章

  1. 友盟用户反馈(官方文档学习而来)
  2. SHELL DATE 命令详解
  3. 存储卡 SD/MMC/MS/CF/XD/SM/MICRO SD
  4. 微信小程序退款 报错 FAIL 证书验证失败
  5. 预防死锁的方法以及死锁的检测与解除
  6. 腾讯视频Node.js服务是如何支撑国庆阅兵直播高并发的?
  7. 数据结构/排序/选择排序/简单选择排序
  8. File “C:\Users\hjl\AppData\Local\Programs\Python\Python38\lib\site-packages\pymysql\err.py“, line 1
  9. unzip unbuntu 中文乱码
  10. 波特率、比特率 与数据传输速率的区别