流与集合的不同
-
没有存储。
流不是存储元素的数据结构; 相反,它通过计算操作的流水线传送诸如数据结构,阵列,生成器功能或I / O通道的源的元件。
-
功能性质。
流上的操作产生结果,但不会修改其来源。 例如,过滤从Stream获得的Stream会生成新的Stream而不需要过滤的元素,而不是从源集合中删除元素。
-
·懒惰寻求。
许多流操作(如过滤,映射或重复删除)可以懒惰地实现,从而暴露优化的机会。 例如,“找到具有三个连续元音的第一个String ”不需要检查所有的输入字符串。 流操作分为中间( Stream生产)操作和终端(价值或副作用生成)操作。 中级操作总是懒惰。
-
可能无限。
虽然集合的大小有限,但流不需要。 诸如limit(n)或findFirst()之类的limit(n) findFirst()可以允许无限流上的计算在有限的时间内完成。
-
消耗品
流的元素只能在流的一生中访问一次。 像Iterator一样 ,必须生成一个新流来重新访问源的相同元素。
获得流的方法
- 从Collection通过stream()和parallelStream()方法;
- 从阵列通过Arrays.stream(Object[]) ;
- 从上流类静态工厂的方法,如Stream.of(Object[]) , IntStream.range(int,int)或Stream.iterate(Object, UnaryOperator) ;
- 文件的行可以从BufferedReader.lines()获取 ;
- 文件路径的流可以从Files中的方法获得;
- 随机数流可以从Random.ints()获得;
- 许多其它的数据流的方法的轴承在JDK,包括BitSet.stream() ,
Pattern.splitAsStream(java.lang.CharSequence)和JarFile.stream() 。
Demo
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
*
* @author shirley
* @date 2019/9/4
*/
public class StreamTest {
public static void main(String[] args) {
/**
* test1
*/
System.out.println("test1 start");
IntStream s1 =Arrays.stream(new int[]{3,4,5});
long n = s1.filter(i->i<4).count();
System.out.println(n);
System.out.println("test1 end");
/**
* test2
*/
System.out.println("test2 start");
Integer[] objs = new Integer[]{35,6};
System.out.println(Stream.of(objs).filter(i->i>7).count());
System.out.println("test2 end");
/**
* test3
*/
System.out.println("test3 start");
int sum=0;
IntStream s2 = Arrays.stream(new int[]{354, 45, 55});
sum = s2.sum();
s2 = Arrays.stream(new int[]{354, 45, 55});
s2.forEach(System.out::println);
IntStream.range(1,3).forEach(System.out::println);
IntStream.rangeClosed(1,3).forEach(System.out::println);
System.out.println(sum);
System.out.println("test3 end");
/**
* test4
*/
System.out.println("test4 start");
Item item1 = new Item("red",1);
Item item2 = new Item("blue",2);
Item item3 = new Item("white",3);
List<Item> list = new ArrayList<>();
list.add(item1);
list.add(item2);
list.add(item3);
System.out.println(list.stream().filter(item->item.getColor()=="blue").mapToInt(Item::getWeight).sum());
System.out.println("test4 end");
/**
* test5
*/
System.out.println("test5 start");
IntStream s3 = Arrays.stream(new int[]{354, 45, 55});
int[] array = s3.toArray();
for(int i=0;i<array.length;i++) {
System.out.print(array[i]+" ");
}
System.out.println();
List<Integer> weights = list.stream().mapToInt(Item::getWeight).collect(ArrayList::new,List::add,(left,right)->{
left.addAll(right);
});
System.out.println(weights);
Set<Item> items = list.stream().collect(Collectors.toSet());
System.out.println(items);
/*joining()
容器: StringBuilder::new
加入容器操作: StringBuilder::append
多容器合并: r1.append(r2); return r1;
聚合后的结果操作: StringBuilder::toString*/
Stream stringStream =Arrays.stream(new String[]{"3","4","5"});
String string1 = (String)stringStream.collect(Collectors.joining());
System.out.println(string1);
List<Item> items2 = list.stream().collect(Collectors.toList());
System.out.println(items2);
System.out.println("test5 end");
/**
* test6
*/
System.out.println("test6 start");
IntStream s6 =Arrays.stream(new int[]{3,4,5});
List<Integer> list6= s6.map(i->i*i).collect(ArrayList::new,List::add,(left,right)->{
left.addAll(right);
});
System.out.println(list6);
System.out.println("test6 end");
/**
* test7
*/
System.out.println("test7 start");
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
System.out.println("test7 end");
/**
* test8
*/
System.out.println("test8 start");
Optional.ofNullable("ok").ifPresent(System.out::println);
System.out.println(Optional.ofNullable("ok").map(String::length).orElse(-1));
System.out.println("test8 end");
/**
* test9
*/
System.out.println("test9 start");
String concat = Stream.of("a","b","c","d").reduce("",String::concat);
System.out.println(concat);
System.out.println("test9 end");
/**
* test10
*/
System.out.println("test10 start");
System.out.println(list.stream().map(Item::getColor).limit(2).skip(1).collect(Collectors.toSet()));
System.out.println("test10 end");
/**
* test11
*/
System.out.println("test11 start");
Random seed = new Random();
Supplier<Integer> random = seed::nextInt;
Stream.generate(random).limit(10).forEach(System.out::println);
System.out.println("test11 end");
/**
* test12
*/
System.out.println("test12 start");
Stream.iterate(0,i->i+3).limit(3).forEach(System.out::println);
System.out.println("test12 end");
}
}
class Item{
private String color;
private Integer weight;
Item(String color,Integer weight){
this.color=color;
this.weight=weight;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
Stream特性:
- 所有 Stream 的操作必须以 lambda 表达式为参数
- 并行能力,当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并行进行的。
- 可以是无限的
Reference:
1.https://blog.fondme.cn/apidoc/jdk-1.8-google/
2.https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/index.html