目录

  • java8新特性介绍:
  • lamda表达式的介绍和使用:
    • 函数式接口:
    • 方法引用:
    • 构造器引用:
  • stream流
    • Stream流的创建:
    • 流的中间操作:
      • 筛选(filter)
      • 映射(map/flatMap)
      • 排序(sorted)
      • 提取/组合:concat,distinct,limit,skip:
    • 流的终止操作:
      • 1.终止操作:遍历(foreach)
      • 2.终止操作:匹配(find/match)
      • 3.终止操作:归约(reduce)
      • 4.终止操作:聚合(max/min/count)
      • 5.终止操作:收集(collect)
    • Optionnal类:

java8新特性介绍:

速度更快是因为hashmap等结构进行了改变升级,换成了数组+链表+红黑树,查询效率等大大提高。

jdk1.8内存结构的更新:

lamda表达式的介绍和使用:

lamda语法:

需求一:

需求二:


package com.fan.yygh.hosp;import org.junit.jupiter.api.Test;public class lamdaTest {@Testpublic void test01(){Runnable runnable = () -> {System.out.println("Hello ,lamda");};runnable.run();}
}

总结:左右遇一括号省,左侧推断类型省,能省则省

使用:


将lamda表达式像所有的数据一样来回传递。
自定义函数接口:

@FunctionalInterface
interface myFunction<T,R> {//有2个参数需要处理public R getValue(T t1,T t2);
}
package com.fan.yygh.hosp;import org.junit.jupiter.api.Test;import java.util.Comparator;
import java.util.function.Consumer;public class lamdaTest {@Test//1.无参数无返回值的lamda表达式public void test01(){Runnable runnable = () -> {System.out.println("Hello ,lamda");};runnable.run();}@Test//2.有一个参数无返回值的lamda表达式public void test02(){Consumer<String> consumer = (x) -> System.out.println(x);consumer.accept("测试");}@Test//3.有2个参数有返回值的lamda表达式public void test03(){Comparator<Integer> comparator = (x, y) ->{System.out.println("函数式接口");return Integer.compare(1,2);};}@Test//3.有2个参数有返回值的lamda表达式public void test04(){Comparator<Integer> comparator = (x, y) -> Integer.compare(1,2);};//练习题最后一个答案:@Testpublic void test05(){TestLamd testLamd = new TestLamd();testLamd.sum(100L,200L,(A,B) -> {return A+B;});testLamd.sum(100l,200l,(a,b) -> a*b );}private class TestLamd {public void sum (Long a,Long b,myFunction<Long,Long> myFunction){System.out.println(myFunction.getValue(a,b));}}/*========end========*/
}

函数式接口:

1.Consumer<T> :消费型接口
void accept(T t);2.Supplier:供给型接口
T get();3.Function<T,R>:函数型接口
R apply(T t);4.Predicate<T>:断言型接口
boolean test(T t);

lamda表达式的-》后的用于实现函数是接口的具体实现;

方法引用:

构造器引用:


stream流

1.什么是Stream流?

在Java 8中,得益于Lambda所带来的函数式编程, 引入了一个全新的Stream流概念。

目的:用于简化集合和数组操作的API。

2.Stream流式思想的核心:

1、先得到集合或者数组的Stream流(就是一根传送带)
2、把元素放上去
3、然后就用这个Stream流简化的API来方便的操作元素。

3.Stream流的作用是什么,结合了什么技术?
简化集合、数组操作的API。结合了Lambda表达式。

4.说说Stream流的思想和使用步骤。
1、先得到集合或者数组的Stream流(就是一根传送带)。
2、把元素放上去。
3、然后就用这个Stream流简化的API来方便的操作元素。

Stream流的获取
Stream流的操作的三个步骤:
1、获取Stream流——>创建一条流水线,并把数据放到流水线上准备进行操作.
2、中间方法——>流水线上的操作。一次操作完毕之后,还可以继续进行其他操作.
3、终结方法——>一个Stream流只能有一个终结方法,是流水线上的最后一个操作.

注:Stream操作集合或者数组的第一步是先得到Stream流,然后才能使用流的功能。

Stream流的创建:

常见的创建流的4种方式:

1、通过 java.util.Collection.stream() 方法用集合创建流

List<String> list = Arrays.asList("a", "b", "c");
// 创建一个顺序流
Stream<String> stream = list.stream();
// 创建一个并行流
Stream<String> parallelStream = list.parallelStream();

2、使用java.util.Arrays.stream(T[] array)方法用数组创建流

 //  数组获取流的方式
Stream<String> namesStream = Arrays.stream(数组名array);int[] array={1,3,5,6,8};
IntStream stream = Arrays.stream(array);

3、通过Stream类中的静态方法of()来创建流

 Stream<String> stream3 = Stream.of("a", "b", "c");Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

4、由函数生成流—创建无限流:Stream.iterate和Stream.generate:

Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println);Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);

@Test //流的创建public void test01(){//1.通过集合Collections集合提供的stream()或者parallelStream()ArrayList<Integer> list = new ArrayList<Integer>( Arrays.asList(1, 2, 3, 4));Stream<Integer> stream1 = list.stream();//Stream<Integer> parallelStream = list.parallelStream();//2.数组获取流的方式,通过Arrays中的静态方法stream()获取数组流int[] arr = new int[]{1,2,3,4};IntStream stream2 = Arrays.stream(arr);stream2.filter((x) -> x>2).forEach(System.out::println);//3.通过Stream类中的静态方法of()来获取流Stream<String> stream3 = Stream.of("a", "b", "c");//4.由函数生成流---创建无限流:Stream.iterate和Stream.generate:// 4.1,iterate:从0开始,一直在原来数的基础上增加2来生产一个流/*static <T> Stream<T> iterate​(T seed, UnaryOperator一元运算<T> f)static <T> Stream<T> iterate​(T seed, Predicate<? super T> hasNext,UnaryOperator<T> next)*/Stream.iterate(0,(x)->x+2).limit(3).forEach(System.out::println);//4.2,static <T> Stream<T> generate​(Supplier<? extends T> s)// generate​该方法主要用于生成一个无限连续的无序流,// 流中的元素由用户定义的supplier函数生成Stream.generate( ()-> Math.random() ) //generate的参数是Supplier供给型接口.limit(5) //获取前5个元素,用于限制无限流的长度为5,如果没有limit则死循环输出.forEach(System.out::println); //遍历输出}
static <T> Stream<T> iterate​(T seed, UnaryOperator<T> f)
首先说一个两个参数的iterate,第一个参数是新流中的初始元素,
然后使用该数据做第二个参数也就是UnaryOperator函数的
入参去计算第二元素,然后把新计算得到的第二个元素作为
入参继续计算第三个元素,以此循环可以制造无限个元素,
在实际使用中一般使用limit(n)方法去获取包含n个的流。看一个例子:
Stream.iterate(0,(x)->x+2).limit(3).forEach(System.out::println); //输出0,2,4

流的中间操作:

中间操作分四类:筛选filter,映射map,排序sort,提取和组合

筛选(filter)

筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作

该方法会接收一个返回boolean的函数作为参数,终返回一个包括所有符合条件元素的流

案例一:筛选出Integer集合中大于2的元素,并打印出来

//中间操作@Testpublic void test02(){//筛选(filterArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4));list.stream().filter( x -> x >2 ) //过滤条件,当流中数据大于2的时候放入新流中.forEach(System.out::println); //遍历输出
//案例二:
//获取所有年龄20岁以下的学生ArrayList<Student> students = new ArrayList<>();students.add(new Student(1,19,"张三","M",true));students.add(new Student(1,18,"李四","M",false));students.add(new Student(1,21,"王五","F",true));students.add(new Student(1,20,"赵六","F",false));students.stream().filter(student -> student.getAge()<20);}

案例二: 筛选员工中工资高于8000的人,并形成新的集合。 形成新集合依赖collect(收集),后文有详细介绍。
实体类:

package com.fan.yygh.hosp;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {private String name;  // 姓名private int salary; // 薪资private int age; // 年龄private String sex; //性别private String area;  // 地区
}
 //案例二:
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));List<String> listName = personList.stream().filter((x) -> x.getSalary() > 8000) //条件过滤工资.map(Person::getName) //提取工资大于8000的人的名字.collect(Collectors.toList());//转成list
System.out.println(listName);

映射(map/flatMap)

映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap:

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

映射(map/flatMap)

在对集合进行操作的时候,我们经常会从某些对象中选择性的提取某些元素的值,就像编写sql一样,指定获取表 中特定的数据列

1.指定获取特定列 SELECT name FROM student
2.在Stream API中也提供了类似的方法,map()。它接收一个函数作为方法参数,这个函数会被应用到集合中每一个 元素上,并终将其映射为一个新的元素。 案例:获取所有学生的姓名,并形成一个新的集合

//案例一:获取所有学生的姓名,并形成一个新的集合//中间操作map@Testpublic void test03(){//map的案例一ArrayList<Student> list = new ArrayList<>(Arrays.asList(new Student("张三",12,"man"),new Student("李四",32,"man"),new Student("王五",22,"woman"),new Student("赵六",45,"woman")));list.stream()//.map( Student::getName) //这里使用引用.map( (stu)->stu.getName() ).forEach(System.out::println);//案例二:英文字符串数组的元素全部改为大写。整数数组每个元素+3。System.out.println("案例一:英文字符串数组的元" +"素全部改为大写。整数数组每个元素+3。");String[] arr = new String[] {"abcd", "bcdd", "defde", "fTr" };Arrays.stream(arr).map( (s)->s.toUpperCase()/*映射规则*/).forEach(System.out::println);int[] intArr = new int[]{1,2,3,4};Arrays.stream(intArr).map((x) -> x+3).forEach(System.out::println);}

案例三:将员工的薪资全部增加1000。

//案例三.将员工的薪资全部增加1000。
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
// 不改变原来员工集合的方式
List<Person> listNew = personList.stream().map((person) -> {Person p = new Person(person.getName(), 0, 0, null, null);p.setSalary(person.getSalary() + 1000);//设置新工资return p; //返回新person}).collect(Collectors.toList());//转成集合list
System.out.println("一次改动前:" + personList);
System.out.println("一次改动后:" + listNew);// 改变原来员工集合的方式List<Person> list2 = personList.stream().map((person) -> {person.setSalary(person.getSalary() + 1000);return person;}).collect(Collectors.toList());System.out.println(list2);

排序(sorted)

sorted,中间操作。有两种排序:

sorted():自然排序,流中元素需实现Comparable接口
sorted(Comparator com):Comparator排序器自定义排序

排序:

案例一:自然排序:

//自然排序:流中元素需实现Comparable接口
List<String> stringList = Arrays.asList("ccc", "aaa", "bbb", "ddd");
stringList.stream().sorted().forEach(System.out::println);
//输出: aaa,bbb,ccc,ddd

案例二:将员工按工资由高到低(工资一样则按年龄由大到小)排序:

//定制排序List<Person> personList = new ArrayList<Person>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));personList.add(new Person("Anni", 8200, 24, "female", "New York"));personList.add(new Person("Owen", 9500, 25, "male", "New York"));personList.add(new Person("Alisa", 7900, 26, "female", "New York"));personList.stream().sorted( (e1,e2)->{//自己实现比较规则if( e1.getSalary() == e2.getSalary()){//如果工资相等return e1.getAge()-e2.getAge();//则按照年龄排序}else{//如果工资不相等,按照工资排序return -(e1.getSalary()-e2.getSalary() );}}).forEach(System.out::println);
}

输出:
···
Person(name=Owen, salary=9500, age=25, sex=male, area=New York)
Person(name=Tom, salary=8900, age=23, sex=male, area=New York)
Person(name=Anni, salary=8200, age=24, sex=female, area=New York)
Person(name=Alisa, salary=7900, age=26, sex=female, area=New York)
Person(name=Lily, salary=7800, age=21, sex=female, area=Washington)
Person(name=Jack, salary=7000, age=25, sex=male, area=Washington)
···

提取/组合:concat,distinct,limit,skip:

合并:concat
去重:distinct
获得前几个数据:limit
跳过前几个数据再获取其他:skip

使用案例:

@Test
public void test05(){String[] arr1 = { "a", "b", "c", "d","c" };String[] arr2 = { "d", "e", "f", "g" };//1.合并连接:Stream.concat(stream1,stream2)System.out.println("合并:");Stream<String> stream1 = Stream.of(arr1);Stream<String> stream2 = Stream.of(arr2);Stream.concat(stream1,stream2).forEach(System.out::print); //abcddefg//2 .去重,去除重复元素System.out.println("\n去重:");Arrays.stream(arr1).distinct().forEach(System.out::print);// 3.limit:限制从流中获得前n个数据System.out.println();Stream.iterate(0,x->x+2).limit(5) //获取前5个数据.forEach(System.out::println);// 4.skip:跳过前n个数据Stream.generate(Math::random).limit(10)//获取前10个数.skip(5) //并跳过前5个数.forEach(System.out::println);
}

其他案例:

流的终止操作:

1.终止操作:遍历(foreach)

和集合的遍历输出一样的效果:

//1.遍历foreachList<Integer> list = Arrays.asList(7, 6, 9, 3, 8);list.stream().forEach(System.out::println); //遍历输出

2.终止操作:匹配(find/match)

@Test //终止操作public void test06(){//1.遍历foreachList<Integer> list = Arrays.asList(7, 6, 9, 3, 8);list.stream().forEach(System.out::println); //遍历输出//2.匹配(find/match)//findFirst:  匹配第一个Optional<Integer> first = list.stream().findFirst(); //不能再使用其他终止操作forEachSystem.out.println("匹配第一个:"+first.get());//findAny:匹配任意(适用于并行流)Optional<Integer> any = list.parallelStream().findAny();System.out.println("找到任意一个:"+any.get());//match案例3个://allMatch:检查是否匹配所有元素boolean b1 = list.stream().allMatch(x -> x > 2);System.out.println("检查是否所有元素大于2:"+b1);//anyMatch:检查是否至少匹配一个元素boolean b2 = list.stream().anyMatch(x -> x > 2);System.out.println("检查是否至少有一个元素大于2:"+b2);//noneMatch:检查是否没有 匹配所有元素boolean b3 = list.stream().noneMatch(x -> x > 2);System.out.println("检查是否没有 大于2的元素:"+b3);}



3.终止操作:归约(reduce)

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

案例一:求Integer集合的元素之和、乘积和最大值。

@Test
public void reducetest(){List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);// 求和方式1Optional<Integer> reduce = list.stream().reduce((x, y) -> x + y);System.out.println("求和方式1:"+reduce.get());// 求和方式2Optional<Integer> reduce1 = list.stream().reduce(Integer::sum);//调用包装类Integer的静态方法sum()System.out.println("求和方式2,Integer的静态方法sum:"+reduce1.get());// 求和方式3Integer reduce2 = list.stream().reduce(0, Integer::sum);//参数一是用来保存归并参数的初始值,参数二是计算方法System.out.println("求和方式3:"+reduce2);// 求乘积Optional<Integer> reduce3 =list.stream().reduce((a, b) -> a * b);//参数是2个// 求最大值方式1Optional<Integer> reduce4 =list.stream().reduce((x, y) -> x > y ? x : y);// 求最大值写法2Optional<Integer> reduce5 = list.stream().reduce(Integer::max);Optional<Integer> reduce6 = list.stream().reduce(Integer::min);System.out.println("最大值:"+reduce5.get());System.out.println("最小值:"+reduce6.get());
}

案例二:求所有员工的工资之和和最高工资。

 //求所有员工的工资之和和最高工资。
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
// 求工资之和方式1:推荐
Optional<Integer> reduce7 = personList.stream().map(Person::getSalary) //映射出所有的工资.reduce(Integer::sum);
System.out.println("求工资之和方式1:"+reduce7.get());
// 求工资之和方式2:
Integer sumSalary2 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(),(sum1, sum2) -> sum1 + sum2);
// 求工资之和方式3:
Integer sumSalary3 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(),Integer::sum);// 求最高工资方式3:推荐
Integer maxSalary3 = personList.stream().map(Person::getSalary).reduce(Integer::max).get();
// 求最高工资方式1:
Integer maxSalary = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),Integer::max);
// 求最高工资方式2:
Integer maxSalary2 = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),(max1, max2) -> max1 > max2 ? max1 : max2);

4.终止操作:聚合(max/min/count)

max、min、count这些字眼你一定不陌生,没错,在mysql中我们常用它们进行数据统计。Java stream中也引入了这些概念和用法,极大地方便了我们对集合、数组的数据统计工作

案例一:获取String集合中最长的元素。

public class StreamTest {public static void main(String[] args) {List<String> list =Arrays.asList("adnm", "admmt", "pot", "xbangd", "weoujgsd");Optional<String> max = list.stream().max(Comparator.comparing(String::length));System.out.println("最长的字符串:" + max.get());}
}

案例二:获取Integer集合中的最大值。

List<Integer> list = Arrays.asList(7, 6, 9, 4, 11, 6);// 自然排序
Optional<Integer> max = list.stream().max(Integer::compareTo);
// 自定义排序(从大到小排序)
Optional<Integer> max2 = list.stream().max((o1, o2) -> o2 - o1);
System.out.println("自然排序的最大值:" + max.get());
System.out.println("自定义排序的最大值:" + max2.get());

案例三:获取员工薪资最高的人。

 //案例三:获取员工薪资最高的人。List<Person> personList = new ArrayList<Person>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));personList.add(new Person("Anni", 8200, 24, "female", "New York"));personList.add(new Person("Owen", 9500, 25, "male", "New York"));personList.add(new Person("Alisa", 7900, 26, "female", "New York"));Optional<Person> max1 = personList.stream().max(Comparator.comparingInt(Person::getSalary));System.out.println("最大工资的人:"+max1.get());

count案例:
案例四:计算Integer集合中大于6的元素的个数。

List<Integer> list = Arrays.asList(7, 6, 4, 8, 2, 11, 9);long count = list.stream().filter(x -> x > 6).count();
System.out.println("list中大于6的元素个数:" + count);

5.终止操作:收集(collect)


使用toMap()函数之后,返回的就是一个Map了,自然会需要key和value。
toMap()的第一个参数就是用来生成key值的,第二个参数就是用来生成value值的。
第三个参数用在key值冲突的情况下:如果新元素产生的key在Map中已经出现过了,第三个参数就会定义解决的办法。

在.collect(Collectors.toMap(Person::getId, v -> v, (a,b)->a))中:
第一个参数:Person:getId表示选择Person的getId作为map的key值;

第二个参数:v->v表示选择将原来的对象作为Map的value值

第三个参数:(a,b)->a中,如果a与b的key值相同,选择a作为那个key所对应的value值。



并行流和顺序流:

Optionnal类:

Stream流-详细相关推荐

  1. stream流_最详细的JDK8新特性————Stream流

    Stream流 在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊 端. 传统集合的多步遍历代码: 几乎所有的集合(如Collect ...

  2. JAVA的stream流操作详细解析

    java的stram流操作 为什么需要 Stream 流与集合的区别 对比:原始集合操作与Stream集合操作 (过滤/映射/扁平化/遍历/排序/去重/跳过/截断的应用) 流的组成 流操作的分类 流的 ...

  3. Stream流:基本API操作详细笔记

    目录 1.Stream流基础介绍 1.1 Stream流有一些特性: 1.2 流的操作可以分为两种类型: 2.创建流 2.1 串行流: 2.2 并行流 3.操作流 3.1 过滤 3.2 映射 3.3 ...

  4. 【Java10】lambda表达式(函数式编程),Stream流,File类,字节/字符流,乱码,缓冲/转换/序列化/打印流,Properties

    文章目录 1.lambda表达式标准语法:()->{} 2.lambda表达式简略语法:可推导即可省略 3.lambda表达式原理:lambda效率比匿名内部类高 4.两个函数式接口:Consu ...

  5. 跟我学 Java 8 新特性之 Stream 流(六)收集

    转载自   跟我学 Java 8 新特性之 Stream 流(六)收集 我们前面的五篇文章基本都是在说将一个集合转成一个流,然后对流进行操作,其实这种操作是最多的,但有时候我们也是需要从流中收集起一些 ...

  6. 跟我学 Java 8 新特性之 Stream 流基础体验

    转载自   跟我学 Java 8 新特性之 Stream 流基础体验 Java8新增的功能中,要数lambda表达式和流API最为重要了.这篇文章主要介绍流API的基础,也是流API系列的第一篇文章, ...

  7. 跟我学 Java 8 新特性之 Stream 流(二)关键知识点

    转载自   跟我学 Java 8 新特性之 Stream 流(二)关键知识点 我们的第一篇文章,主要是通过一个Demo,让大家体验了一下使用流API的那种酣畅淋漓的感觉.如果你没有实践,我还是再次呼吁 ...

  8. Oracle Stream配置详细步骤

    Oracle Stream配置详细步骤 作者: 杨宝秋, 出处:IT168 1 引言 Oracle Stream功能是为提高数据库的高可用性而设计的,在Oracle 9i及之前的版本这个功能被称为Ad ...

  9. Java利用stream(流)对map中的values进行过滤、排序操作

    前言 对于Java8中的stream(流)这种优雅.方便.快捷.高效的操作已经是信手沾来了吧,但是却仅限List.Set.难道我Map不要面子得嘛?在工作中需要对从List转Map的数据进行操作,因此 ...

最新文章

  1. 〖Java〗Eclispe安装和使用viplugin
  2. AI可以写软件了,所以程序员要下岗?
  3. 学习ansible playbook之前先了解下YAML语法
  4. lucene源码分析(1)基本要素
  5. 确定进制(信息学奥赛一本通-T1413)
  6. GIL线程全局锁 协程
  7. http 几种请求方法的差别
  8. python可哈希_Python,TypeError:不可哈希类型:'list'
  9. Photoshop1:入门实用技巧
  10. Activity/Fragment最强生命周期总结
  11. pku2192---Zipper(动态规划题,随机组合两个字符串)
  12. 大功率MOS管选型手册及可申请样品-KIA MOS管
  13. python语法报错_1、Python语法及报错总结 - 随笔分类 - 走路带风的帅界扛把子 - 博客园...
  14. gltf 2.0快速入门
  15. 各编程语言中的注释格式
  16. 13部成功预知未来科技的科幻电影
  17. opencv android安装教程,opencv for android安装教程.doc
  18. 学习TypeScrip2(任意类型)
  19. 【问题描述】建立一个通讯录的结构记录,包括姓名、生日、电话号码。输入n(n<10)个朋友的信息,再按他们的年龄从大到小的顺序依次输出其信息
  20. 58同城iOS客户端Hybrid框架探索

热门文章

  1. 机构层级列表递归展示查询,并优化SQL查询
  2. 基于JSP的民宿酒店管理系统【数据库设计、源码、开题报告】
  3. 计算机一级b考试试题2016,计算机一级B考试试题及答案2016
  4. 疯狂英语学习者的经典名句
  5. STM32F407-OV7670(无FIFO)-ONENET-实现摄像头画面上传到onenet(EDP协议)
  6. ASP.NET AJAX---TimerHiddenField控件小实例 (实现倒计时)
  7. 【附源码】计算机毕业设计JAVA教学质量评价系统
  8. 高清投影仪哪个好,全新内容10大高清投影仪让你知道
  9. 如何两个月刷400道leetcode
  10. 利用Python实现每天给自己的邮箱按照艾宾浩斯曲线发送单词