一、概述

Stream 是一组用来处理数组、集合的API,Stream API 提供了一种高效且易于使用的处理数据的方式。

Java 8 中之所以费这么大的功夫引入 函数式编程 ,原因有两个:

  • 代码简洁函数式编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环。
  • 多核友好,Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是用用一下parallel()方法
  • Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作

二、Stream特性

1、不是数据结构,没有内部存储,不会保存数据,故每个Stream流只能使用一次

2、不支持索引访问

3、支持并行

4、很容易生成数据或集合(List,Set)

5、支持过滤、查找、转换、汇总、聚合等操作

6、延迟计算,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算

三、分类

关于应用在Stream流上的操作,可以分成两种:

  1. Intermediate(中间操作): 中间操作的返回结果都是Stream,故可以多个中间操作叠加;
  2. Terminal(终止操作): 终止操作用于返回我们最终需要的数据,只能有一个终止操作。

使用Stream流,可以清楚地知道我们要对一个数据集做何种操作,可读性强。而且可以很轻松地获取并行化Stream流,不用自己编写多线程代码,可以让我们更加专注于业务逻辑。



无状态: 指元素的处理不受之前元素的影响;

有状态: 指该操作只有拿到所有元素之后才能继续下去。

非短路操作: 指必须处理所有元素才能得到最终结果;

短路操作: 指遇到某些符合条件的元素就可以得到最终结果,如 A || B,只要A为true,则无需判断B的结果。

四、Stream的创建

1、通过数组来生成

2、通过集合来生成

3、通过Stream.generate方法来创建

4、通过Stream.iterate方法来创建

5、其他Api创建

4.1 通过数组来生成

 //通过数组来生成
static void gen1(){
String[] strs = {"a","b","c","d"};
Stream<String> strs1 = Stream.of(strs);//使用Stream中的静态方法:of()
strs1.forEach(System.out::println);//打印输出(a、b、c、d)
}

4.2 通过集合来生成

//通过集合来生成
static void gen2(){
List<String> list = Arrays.asList("1","2","3","4");
Stream<String> stream = list.stream();//获取一个顺序流
stream.forEach(System.out::println);//打印输出(1,2,3,4)
}

4.3 通过Stream.generate方法来创建

    //generate
static void gen3(){
Stream<Integer> generate = Stream.generate(() -> 1);//使用Stream中的静态方法:generate()
//limit 返回由该流的元素组成的流,截断长度不能超过maxSize
generate.limit(10).forEach(System.out::println);//打印输出(打印10个1)
}

4.4 通过Stream.iterate方法来创建

    //使用iterator
static void gen4() {
Stream<Integer> iterate = Stream.iterate(1, x -> x + 1);//使用Stream中的静态方法:iterate()
iterate.limit(10).forEach(System.out::println);//打印输出(1,2,3,4,5,6,7,8,9,10)
}

4.4 其他Api创建

//其他方式
static void gen5(){
String str = "abcdefg";
IntStream stream =str.chars();//获取str 字节码
stream.forEach(System.out::println);//打印输出(97,98,99,100,101,102,103)
}

五、Stream的常用API

5.1 中间操作

1. filter: 过滤流中的某些元素
 //中间操作:如果调用方法之后返回的结果是Stream对象就意味着是一个中间操作
Arrays.asList(1,2,3,4,5).stream()//获取顺序流
.filter((x)->x%2==0) // 2 4
.forEach(System.out::println); //求出结果集中所有偶数的和
int count = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream()//获取顺序流
.filter(x -> x % 2 == 0).// 2 4 6 8
mapToInt(x->x).sum();//求和
System.out.println(count); //打印输出 20
2. distinct: 通过流中元素的 hashCode() 和 equals() 去除重复元素
 Arrays.asList(1,2,3,3,3,4,5,2).stream()//获取顺序流
.distinct()//去重
.forEach(System.out::println);// 打印输出(1,2,3,4,5) System.out.println("去重:---------------"); Arrays.asList(1,2,3,3,3,4,5,2).stream()//获取顺序流
.collect(Collectors.toSet())//Set()去重
.forEach(System.out::println);// 打印输出(1,2,3,4,5)
3. 排序

sorted():返回由此流的元素组成的流,根据自然顺序排序。

sorted(Comparator com):返回由该流的元素组成的流,根据提供的 Comparator进行排序。

//获取最大值和最小值但是不使用min和max方法
List<Integer> list = Arrays.asList(1,2, 3,4, 5, 6);
Optional<Integer> min = list.stream().sorted().findFirst();//自然排序 根据数字从小到大排列
System.out.println(min.get());//打印输出(1) Optional<Integer> max2 = list.stream().sorted((a, b) -> b - a).findFirst();//定时排序 根据最大数进行排序
System.out.println(max2.get());//打印输出(6) //按照大小(a-z)排序
Arrays.asList("java","c#","python","scala").stream().sorted().forEach(System.out::println);
//按照长度排序
Arrays.asList("java","c#","python","scala").stream().sorted((a,b)->a.length()-b.length()).forEach(System.out::println);
4. 截取

limit(n):返回由此流的元素组成的流,截短长度不能超过 n

skip(n):在丢弃流的第n元素后,配合limit(n)可实现分页

//打印20-30这样的集合数据
Stream.iterate(1,x->x+1).limit(50)// limit 50 总共到50
.skip(20)// 跳过前 20
.limit(10) // 打印10个
.forEach(System.out::println);//打印输出(21,22,23,24,25,26,27,28,29,30)
5. 转换

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

List<String> list = Arrays.asList("a,b,c", "1,2,3");

//将每个元素转成一个新的且不带逗号的元素
Stream<String> s1 = list.stream().map(s -> s.replaceAll(",", ""));
s1.forEach(System.out::println); // abc 123 Stream<String> s3 = list.stream().flatMap(s -> {
//将每个元素转换成一个stream
String[] split = s.split(",");
Stream<String> s2 = Arrays.stream(split);
return s2;
});
s3.forEach(System.out::println); // a b c 1 2 3
6. 消费

peek:如同于map,能得到流中的每一个元素。但map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值。

 //将str中的每一个数值都打印出来,同时算出最终的求和结果
String str ="11,22,33,44,55";
System.out.println(Stream.of(str.split(",")).peek(System.out::println).mapToInt(Integer::valueOf).sum());//11 22 33 44 55 165

5.2 终止操作

1. 循环:forEach

Users类:

import java.util.Date;

/**
* @program: lambda
* @ClassName Users
* @description:
* @author: muxiaonong
* @create: 2020-10-24 11:00
* @Version 1.0
**/
public class Users { private String name;
public Users() {} /**
* @param name
*/
public Users(String name) {
this.name = name;
} /**
* @param name
* @return
*/
public static Users build(String name){
Users u = new Users();
u.setName(name);
return u;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "name='" + name + '\'';
}
}
   //创建一组自定义对象
String str2 = "java,scala,python";
Stream.of(str2.split(",")).map(x->new Users(x)).forEach(System.out::println);//打印输出(name='java' name='scala' name='python')
Stream.of(str2.split(",")).map(Users::new).forEach(System.out::println);//打印输出(name='java' name='scala' name='python')
Stream.of(str2.split(",")).map(x->Users.build(x)).forEach(System.out::println);//打印输出(name='java' name='scala' name='python')
Stream.of(str2.split(",")).map(Users::build).forEach(System.out::println);//打印输出(name='java' name='scala' name='python')
2. 计算:min、max、count、sum

min:返回流中元素最小值

max:返回流中元素最大值

count:返回流中元素的总个数

sum:求和

 //求集合中的最大值
List<Integer> list = Arrays.asList(1,2, 3,4, 5, 6);
Optional<Integer> max = list.stream().max((a, b) -> a - b);
System.out.println(max.get()); // 6
//求集合的最小值
System.out.println(list.stream().min((a, b) -> a-b).get()); // 1
//求集合的总个数
System.out.println(list.stream().count());//6
//求和
String str ="11,22,33,44,55";
System.out.println(Stream.of(str.split(",")).mapToInt(x -> Integer.valueOf(x)).sum());
System.out.println(Stream.of(str.split(",")).mapToInt(Integer::valueOf).sum());
System.out.println(Stream.of(str.split(",")).map(x -> Integer.valueOf(x)).mapToInt(x -> x).sum());
System.out.println(Stream.of(str.split(",")).map(Integer::valueOf).mapToInt(x -> x).sum());
3. 匹配:anyMatch、 allMatch、 noneMatch、 findFirst、 findAny

anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false

allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false

noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false

findFirst:返回流中第一个元素

findAny:返回流中的任意元素

List<Integer> list = Arrays.asList(1,2, 3,4, 5, 6);
System.out.println(list.stream().allMatch(x -> x>=0)); //如果集合中的元素大于等于0 返回true
System.out.println(list.stream().noneMatch(x -> x > 5));//如果集合中的元素有大于5的元素。返回false
System.out.println(list.stream().anyMatch(x -> x > 4));//如果集合中有大于四4的元素,返回true
//取第一个偶数
Optional<Integer> first = list.stream().filter(x -> x % 10 == 6).findFirst();
System.out.println(first.get());// 6
//任意取一个偶数
Optional<Integer> any = list.stream().filter(x -> x % 2 == 0).findAny();
System.out.println(any.get());// 2
4.收集器:toArray、collect

collect:接收一个Collector实例,将流中元素收集成另外一个数据结构

Collector<T, A, R> 是一个接口,有以下5个抽象方法:

  1. Supplier<A> supplier();创建一个结果容器A
  2. BiConsumer<A, T> accumulator();:消费型接口,第一个参数为容器A,第二个参数为流中元素T。
  3. BinaryOperator<A> combiner();函数接口,该参数的作用跟上一个方法(reduce)中的combiner参数一样,将并行流中各个子进程的运行结果(accumulator函数操作后的容器A)进行合并。
  4. Function<A, R> finisher();函数式接口,参数为:容器A,返回类型为:collect方法最终想要的结果R。
  5. Set<Characteristics> characteristics();返回一个不可变的Set集合,用来表明该Collector的特征
/**
* @program: lambda
* @ClassName Customer
* @description:
* @author: muxiaonong
* @create: 2020-10-24 11:36
* @Version 1.0
**/
public class Customer { private String name; private Integer age; ...getset忽略
}
 public static void main(String[] args) {
Customer c1 = new Customer("张三",10);
Customer c2 = new Customer("李四",20);
Customer c3 = new Customer("王五",10); List<Customer> list = Arrays.asList(c1,c2,c3); //转成list
List<Integer> ageList = list.stream().map(Customer::getAge).collect(Collectors.toList());
System.out.println("ageList:"+ageList);//ageList:[10, 20, 10] //转成set
Set<Integer> ageSet = list.stream().map(Customer::getAge).collect(Collectors.toSet());
System.out.println("ageSet:"+ageSet);//ageSet:[20, 10] //转成map,注:key不能相同,否则报错
Map<String, Integer> CustomerMap = list.stream().collect(Collectors.toMap(Customer::getName, Customer::getAge));
System.out.println("CustomerMap:"+CustomerMap);//CustomerMap:{李四=20, 张三=10, 王五=10} //字符串分隔符连接
String joinName = list.stream().map(Customer::getName).collect(Collectors.joining(",", "(", ")"));
System.out.println("joinName:"+joinName);//joinName:(张三,李四,王五) //聚合操作
//1.学生总数
Long count = list.stream().collect(Collectors.counting());
System.out.println("count:"+count);//count:3
//2.最大年龄 (最小的minBy同理)
Integer maxAge = list.stream().map(Customer::getAge).collect(Collectors.maxBy(Integer::compare)).get();
System.out.println("maxAge:"+maxAge);//maxAge:20 //3.所有人的年龄
Integer sumAge = list.stream().collect(Collectors.summingInt(Customer::getAge));
System.out.println("sumAge:"+sumAge);//sumAge:40 //4.平均年龄
Double averageAge = list.stream().collect(Collectors.averagingDouble(Customer::getAge));
System.out.println("averageAge:"+averageAge);//averageAge:13.333333333333334 //分组
Map<Integer, List<Customer>> ageMap = list.stream().collect(Collectors.groupingBy(Customer::getAge));
System.out.println("ageMap:"+ageMap);//ageMap:{20=[com.mashibing.stream.Customer@20ad9418], 10=[com.mashibing.stream.Customer@31cefde0, com.mashibing.stream.Customer@439f5b3d]} //分区
//分成两部分,一部分大于10岁,一部分小于等于10岁
Map<Boolean, List<Customer>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));
System.out.println("partMap:"+partMap); //规约
Integer allAge = list.stream().map(Customer::getAge).collect(Collectors.reducing(Integer::sum)).get();
System.out.println("allAge:"+allAge);//allAge:40 }

六、Stream的方法摘要

修饰符和类型 方法和说明
static Collector<T,?,Double> averagingDouble(ToDoubleFunction<? super T> mapper) 返回一个 Collector ,它产生应用于输入元素的双值函数的算术平均值。
static Collector<T,?,Double> averagingInt(ToIntFunction<? super T> mapper) 返回一个 Collector ,它产生应用于输入元素的整数值函数的算术平均值。
static Collector<T,?,Double> averagingLong(ToLongFunction<? super T> mapper) 返回一个 Collector ,它产生应用于输入元素的长值函数的算术平均值。
static <T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher) 适应 Collector进行额外的整理转换。
static Collector<T,?,Long> counting() 返回 Collector类型的接受元件 T计数输入元件的数量。
static <T,K> Collector<T,?,Map<K,List>> groupingBy(Function<? super T,? extends K> classifier) 返回 Collector “由基团”上的类型的输入元件操作实现 T ,根据分类功能分组元素,并且在返回的结果 Map 。
static <T,K,A,D> Collector<T,?,Map<K,D>> groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream) 返回 Collector “由基团”上的类型的输入元件操作实现级联 T ,根据分类功能分组元素,然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。
static <T,K,D,A,M extends Map<K,D>>Collector<T,?,M> groupingBy(Function<? super T,? extends K> classifier, Supplier mapFactory, Collector<? super T,A,D> downstream) 返回 Collector “由基团”上的类型的输入元件操作实现级联 T ,根据分类功能分组元素,然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。
static <T,K> Collector<T,?,ConcurrentMap<K,List>> groupingByConcurrent(Function<? super T,? extends K> classifier) 返回一个并发 Collector “由基团”上的类型的输入元件操作实现 T ,根据分类功能分组元素。
static <T,K,A,D> Collector<T,?,ConcurrentMap<K,D>> groupingByConcurrent(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream) 返回一个并发 Collector “由基团”上的类型的输入元件操作实现级联 T ,根据分类功能分组元素,然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。
static <T,K,A,D,M extends ConcurrentMap<K,D>> Collector<T,?,M> groupingByConcurrent(Function<? super T,? extends K> classifier, Supplier mapFactory, Collector<? super T,A,D> downstream) 返回一个并发 Collector “由基团”上的类型的输入元件操作实现级联 T ,根据分类功能分组元素,然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。
static Collector<CharSequence,?,String> joining() 返回一个 Collector ,按照遇到的顺序将输入元素连接到一个 String中。
static Collector<CharSequence,?,String> joining(CharSequence delimiter) 返回一个 Collector ,按照遇到的顺序连接由指定的分隔符分隔的输入元素。
static Collector<CharSequence,?,String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 返回一个 Collector ,它将按照指定的 Collector分隔的输入元素与指定的前缀和后缀进行连接。
static <T,U,A,R> Collector<T,?,R> mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream) 适应一个 Collector类型的接受元件 U至类型的一个接受元件 T通过积累前应用映射函数到每个输入元素。
static Collector<T,?,Optional> maxBy(Comparator<? super T> comparator) 返回一个 Collector ,它根据给出的 Comparator产生最大元素,描述为 Optional 。
static Collector<T,?,Optional> minBy(Comparator<? super T> comparator) 返回一个 Collector ,根据给出的 Comparator产生最小元素,描述为 Optional 。
static Collector<T,?,Map<Boolean,List>> partitioningBy(Predicate<? super T> predicate) 返回一个 Collector ,根据Predicate对输入元素进行 Predicate ,并将它们组织成 Map<Boolean, List> 。
static <T,D,A> Collector<T,?,Map<Boolean,D>> partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream) 返回一个 Collector ,它根据Predicate对输入元素进行 Predicate ,根据另一个 Collector减少每个分区的值,并将其组织成 Map<Boolean, D> ,其值是下游缩减的结果。
static Collector<T,?,Optional> reducing(BinaryOperator op) 返回一个 Collector ,它在指定的 Collector下执行其输入元素的 BinaryOperator 。
static Collector<T,?,T> reducing(T identity, BinaryOperator op) 返回 Collector执行下一个指定的减少其输入元件的 BinaryOperator使用所提供的身份。
static <T,U> Collector<T,?,U> reducing(U identity, Function<? super T,? extends U> mapper, BinaryOperator op) 返回一个 Collector ,它在指定的映射函数和 BinaryOperator下执行其输入元素的 BinaryOperator 。
static Collector<T,?,DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) 返回一个 Collector , double生产映射函数应用于每个输入元素,并返回结果值的汇总统计信息。
static Collector<T,?,IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper) 返回一个 Collector , int生产映射函数应用于每个输入元素,并返回结果值的汇总统计信息。
static Collector<T,?,LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper) 返回一个 Collector , long生产映射函数应用于每个输入元素,并返回结果值的汇总统计信息。
static Collector<T,?,Double> summingDouble(ToDoubleFunction<? super T> mapper) 返回一个 Collector ,它产生应用于输入元素的双值函数的和。
static Collector<T,?,Integer> summingInt(ToIntFunction<? super T> mapper) 返回一个 Collector ,它产生应用于输入元素的整数值函数的和。
static Collector<T,?,Long> summingLong(ToLongFunction<? super T> mapper) 返回一个 Collector ,它产生应用于输入元素的长值函数的和。
static <T,C extends Collection> Collector<T,?,C> toCollection(Supplier collectionFactory) 返回一个 Collector ,按照遇到的顺序将输入元素累加到一个新的 Collection中。
static <T,K,U> Collector<T,?,ConcurrentMap<K,U>> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper) 返回一个并发的 Collector ,它将元素累加到 ConcurrentMap ,其键和值是将所提供的映射函数应用于输入元素的结果。
static <T,K,U> Collector<T,?,ConcurrentMap<K,U>> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator mergeFunction) 返回一个并发的 Collector ,它将元素累加到一个 ConcurrentMap ,其键和值是将提供的映射函数应用于输入元素的结果。
static <T,K,U,M extends ConcurrentMap<K,U>> Collector<T,?,M> toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier) 返回一个并发的 Collector ,它将元素累加到一个 ConcurrentMap ,其键和值是将所提供的映射函数应用于输入元素的结果。
static Collector<T,?,List> toList() 返回一个 Collector ,它将输入元素 List到一个新的 List 。
static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper) 返回一个 Collector ,它将元素累加到一个 Map ,其键和值是将所提供的映射函数应用于输入元素的结果。
static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator mergeFunction) 返回一个 Collector ,它将元素累加到 Map ,其键和值是将提供的映射函数应用于输入元素的结果。
static <T,K,U,M extends Map<K,U>> Collector<T,?,M> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier) 返回一个 Collector ,它将元素累加到一个 Map ,其键和值是将所提供的映射函数应用于输入元素的结果。
static Collector<T,?,Set> toSet() 返回一个 Collector ,将输入元素 Set到一个新的 Set 。

总结

对于Java中新特性除了 Stream 还有lamaba表达式都是可以帮忙我们很好的去优化代码,使我们的代码简洁且意图明确,避免繁琐的重复性的操作,对于文中有兴趣的小伙伴可以操作起来,又不懂的小伙伴可以在下面进行留言,小农看到了会第一时间回复大家,谢谢,大家加油!

JDK新特性——Stream代码简洁之道的详细用法的更多相关文章

  1. JDK1.8新特性——Stream API

    JDK1.8新特性——Stream API 摘要:本文主要学习了JDK1.8的新特性中有关Stream API的使用. 部分内容来自以下博客: https://blog.csdn.net/icarus ...

  2. JDK新特性关于流操作部分

    // array 工具类 可以用来快捷的将数组转化为list List<String> strings = Arrays.asList("zhongguo", &quo ...

  3. Java8 新特性 Stream() API

    新特性里面为什么要加入流Steam() 集合是Java中使用最多的API,几乎每一个Java程序都会制造和处理集合.集合对于很多程序都是必须的,但是如果一个集合进行,分组,排序,筛选,过滤...这些操 ...

  4. Java8 新特性 Stream 非短路终端操作

    非短路终端操作 Java8 新特性 Stream 练习实例 非短路终端操作,就是所有的元素都遍厉完,直到最后才结束.用来收集成自己想要的数据. 方法有: 遍厉 forEach 归约 reduce 最大 ...

  5. Java8 新特性 Stream 短路终端操作

    短路终端操作 Java8 新特性 Stream 练习实例 传入一个谓词,返回传为boolean,如果符合条件,则直接结束流. 匹配所有 allMatch 任意匹配 anymMatch 不匹配 none ...

  6. Java8 新特性 Stream 无状态中间操作

    无状态中间操作 Java8 新特性 Stream 练习实例 中间无状态操作,可以在单个对单个的数据进行处理.比如:filter(过滤)一个元素的时候,也可以判断,比如map(映射)... 过滤 fil ...

  7. java新特性stream

    java新特性stream,也称为流式编程. 在学习stream之前先了解一下java内置的四大函数 第一种函数式函数,后面是lambda表达式写法 /*Function<String,Inte ...

  8. 史上最全jdk新特性总结,涵盖jdk8到jdk15!

    前言 在本文中,我将描述自第8版以来Java最重要且对开发人员友好的功能.为什么会有这样的主意?在Web上,您可以找到许多文章,其中包含每种Java版本的新功能列表.但是,由于缺少文章,因此无法简要概 ...

  9. 这可能是史上最好的 Java8 新特性 Stream 流教程

    本文翻译自 https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/ 作者: @Winterbe 欢迎关注个人微信公众 ...

随机推荐

  1. hystrix文档翻译之工作原理

    流程图 下面的图片显示了一个请求在hystrix中的流程图. 1.构造一个HystrixCommand或者HystrixObservableCommand对象 第一步是创建一个HystrixComma ...

  2. 1.2Hadoop概述

  3. ServletContex对象学习

    问题: 不同的用户使用相同的数据 解决: ServletContext对象 特点: 服务器创建 用户共享 作用域: 整个项目内 生命周期: 服务器启动到服务器关闭 使用: 1.获取SercvletCo ...

  4. C语言实现数据机构链表的基本操作(从键盘输入生成链表、读取数组生成链表)

    利用头插法实现逆置 下面简单介绍一下,算法思想结合图示看 算法思想:"删除"头结点与链表其他结点的原有联系(即将头结点的指针置空),再逐个插入逆置链表的表头(即"头插&q ...

  5. tomcat在linux下安装

    1.下载地址: https://tomcat.apache.org/download-90.cgi 2.上传linux 3.查看是否上传成功 4.解压: 5.进入后,查看README.md文件,可以查 ...

  6. linux与linux间,互相拷贝文件

    直接使用scp命令 和远程Linux主机 进行文件的拷贝    1.可以将远程Linux系统上的文件拷贝到本地计算机    2.也可以将本地计算机上的文件拷贝到远程Linux系统上. 比如:我们要拷贝 ...

  7. Tomcat 中 catalina.out、catalina.log、localhost.log 和 access_log 的区别

    打开 Tomcat 安装目录中的 log 文件夹,我们可以看到很多日志文件,这篇文章就来介绍下这些日记文件的具体区别. catalina.out 日志 catalina.out 日志文件是 Tomca ...

  8. 动态代理:jdk动态代理和cglib动态代理

    /** * 动态代理类:先参考代理模式随笔,了解代理模式的概念,分为jdk动态代理和cglib,jdk动态代理是通过实现接口的方式创建代理类的,cglib是通过继承类的方式实现的代理类的 * jdk动 ...

  9. Centos-转换或复制文件-dd

    dd 转换或复制文件,同时可以对设备进行备份 相关选项 if 输入文件,可以是设备 of   输出文件,可以是输出设备 bs   指定一个block大小,默认为 512字节 count  指定bs数量

  10. OneWire应用 单总线温度传感器DS18系列

    OneWire DS18S20, DS18B20, DS1822 Temperature DS18B20 The DS18B20 digital thermometer provides 9-bit ...