了解Stram
java8中最重要的改变一个是lambda表达式,另一个则是Stram API(java.util.stram.*)
Stream是java8中处理集合的关键抽象类概念,它可以指定你希望对集合进行的操作,可以知晓非常复杂的查找,过过滤和映射数据等操作.使用streamAPI对集合数据进行操作,就类似使用sql执行的数据库查询,简而言之Stream提供了一种高效且易于使用的处理数据的方式
创建Stream的基本操作
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Main{
public static void main(String[] args) {
//可以通过collection提供的stream()或paralllelStream()获取stream
List<String>list=new ArrayList<>();
Stream<String> stream1=list.stream();
//通过Array中的静态方法stream()获取数组流
Integer [] integers=new Integer[4];
Stream<Integer> stream2 = Arrays.stream(integers);
//通过stream中的静态方法of()
Stream<String>stream3=Stream.of("1","1","2");
//创建无限流
//迭代
Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);
// stream4.forEach(System.out::println);
//生成5个
Stream<Double> limit = Stream.generate(() -> Math.random())
.limit(5);//创建五个
}
}
筛选与切片
中间操作
多个中间操作可以连接起来成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理,二在终止操作时一次性全部处理,成为惰性请求
方法 | 描述 |
---|---|
filter(Predicate p) | 接收lambda,从流水线中排除某些元素 |
distinct() | 筛选,通过流所生成的元素的HAshCode()和equals()去除重复元素 |
limit(long maxSize) | 截断流,使元素不超过给定数量 |
skip(long n) | 跳过元素,返回一个人掉了前n个元素的流.若流中元素不足n个元素.若流中元素不足n个,则返回一个空流.与limit(n)互补 |
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
class User {
private int score;
private int age;
public User(int score, int age){
super();
this.score = score;
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return score == user.score &&
age == user.age;
}
@Override
public int hashCode() {
return Objects.hash(score, age);
}
@Override
public String toString() {
return "User{" +
"score=" + score +
", age=" + age +
'}';
}
}
//内部迭代,迭代操作都由Stream来完成了
class Main{
static List<User>list= Arrays.asList(
new User(1,2),
new User(2,4),
new User(3,6),
new User(3,90),
new User(3,90)
);
public static void main(String[] args) {
//中间操作,不会执行任何操作
//这条语句的意思是去俩条年龄小鱼35的user数据
Stream<User> stream = list.stream().filter((e) -> e.getAge() < 35).limit(2);
//终止操作:一次性执行全部内容
stream.forEach(System.out::println);
//覆盖equals和Hashcode去重
list.stream().distinct().forEach(System.out::println);
}
}
映射
map-接受Lambda,讲元素转换成其他形式或提取信息.接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成为元素
flatMap-接受一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
class User {
private int score;
private int age;
public User(int score, int age){
super();
this.score = score;
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return score == user.score &&
age == user.age;
}
@Override
public int hashCode() {
return Objects.hash(score, age);
}
@Override
public String toString() {
return "User{" +
"score=" + score +
", age=" + age +
'}';
}
}
//内部迭代,迭代操作都由Stream来完成了
class Main{
public static void main(String[] args) {
List<String> list = Arrays.asList("aaa", "bbb", "#ccc", "ddd");
list.stream()
.map((str)->str.toUpperCase()).forEach(System.out::println);
//AAA
//BBB
//#CCC
//DDD
System.out.println("----------------");
//获取String的Hashcode值
list.stream().map(String::hashCode).forEach(System.out::println);
System.out.println("--------------------------");
//因为Main::filterCharcter返回的是Stream<Character>,
//所以整个返回的是Stream<Stream<Character>> 类型
Stream<Stream<Character>> stream = list.stream().map(Main::filterCharcter);
stream.forEach((sm)->{
sm.forEach(System.out::println);//这样就能够逐一输出其中的字符
});
System.out.println("----------------以下可以用floatMap做简化操作");
//这里得到的是一个流,把多个流中的元素抽取出来整合成一个流
// map是把一个个流加入当前的流中,flatmap是把流中一个个元素加到流中
Stream<Character> sm = list.stream().flatMap(Main::filterCharcter);
sm.forEach(System.out::println);//和上面的输出结果是一样的
}
//函数的作用是传入一个string类型,将string类型转成一个个的字符
// 添加到list中并返回list对应的stream
public static Stream<Character>filterCharcter(String str){
List<Character>list=new ArrayList<>();
for (Character ch:str.toCharArray()){
list.add(ch);
}
return list.stream();
}
}
排序
sorted()自然排序 Comparable
sorted(Comparator com)指定排序 Comparator
class Main{
public static void main(String[] args) {
List<Integer>list=Arrays.asList(1,3,5,8,2);
//自然排序 默认是升序
list.stream().sorted().forEach(System.out::println);//1 2 3 5 8
System.out.println("-------");
//指定排序,降序排列
list.stream().sorted((s1,s2)->s2-s1).forEach(System.out::println);//8 5 3 1 2
}
}
终止操作
查找与匹配
boolean allMatch(Predicate<? super T> predicate);-检查是否匹配所有元素,传入一个对应的泛型,返回boolean值
boolean anyMatch(Predicate<? super T> predicate);检查是否匹配一个元素,传入一个对应的泛型,返回boolean
boolean noneMatch(Predicate<? super T> predicate);检查是否没有匹配一个元素,返回boolean
Optional<T> findFirst();返回一个Optional类中,泛型是自己的方法
long count();获取流中的总数
Optional<T> max(Comparator<? super T> comparator);传入比较方法(覆盖Comparator接口),返回最大值
Optional<T> min(Comparator<? super T> comparator);传入比较方法,返回最小值
归约与收集
归约
reduce(T iden,BinaryOperator b)可以将流中元素结合起来得到一个新值
reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值返回Option<T>
map和reduce的连接通常称为map-reduce模式,因google用它来进行网络搜索而出名
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
class User {
private Status status;
private int score;
private int age;
public User(int score, int age,Status status){
super();
this.score = score;
this.age = age;
this.status=status;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public enum Status{
FREE,
BUSY,
VOCATION;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
@Override
public String toString() {
return "User{" +
"status=" + status +
", score=" + score +
", age=" + age +
'}';
}
static List<User> list= Arrays.asList(
new User(1,2,Status.VOCATION),
new User(2,4,Status.FREE),
new User(3,6,Status.FREE),
new User(3,90,Status.VOCATION),
new User(3,90,Status.BUSY)
);
public static void main(String[] args) {
List<Integer>list2=Arrays.asList(1,2,3,4,5,6,7,8,9);
//reduce()第一个参数是初始值,,第二个是二元运算
Integer reduce = list2.stream().reduce(0, (x, y) -> x + y);
System.out.println(reduce);//45
//求出用户年龄的总和
Optional<Integer> reduce1 = list.stream().map(User::getAge).reduce(Integer::sum);
System.out.println("用户年龄总和为:"+reduce1.get());
}
}
收集
collect (Collector c)将流转换为其他形式.接受一个Collector接口的实现,用于给Stream中元素做汇总方法
import java.util.*;
import java.util.stream.Collectors;
class User {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
private Status status;
private int score;
private int age;
public User(int score, int age,Status status,String name){
super();
this.score = score;
this.age = age;
this.status=status;
this.name=name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public enum Status{
FREE,
BUSY,
VOCATION;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
@Override
public String toString() {
return "User{" +
"status=" + status +
", score=" + score +
", age=" + age +
'}';
}
static List<User> list= Arrays.asList(
new User(1,2,Status.VOCATION,"张三"),
new User(2,4,Status.FREE,"李四"),
new User(3,6,Status.FREE,"王五"),
new User(3,90,Status.VOCATION,"赵六"),
new User(3,90,Status.BUSY,"小黑")
);
public static void main(String[] args) {
//取出全部的成绩封装到list集合中
List<Integer> collect = list.stream().map(User::getScore)
.collect(Collectors.toList());
collect.forEach(System.out::println);
//封装到指定的集合当中
HashSet<Integer> collect1 = list.stream().map(User::getScore)
.collect(Collectors.toCollection(HashSet::new));
System.out.println(collect1);//[1, 2, 3]
//计算总用户数量
Long collect2 = list.stream().collect(Collectors.counting());
System.out.println(collect2);//5
//计算年龄总和
Double collect3 = list.stream().collect(Collectors.summingDouble(User::getAge));
System.out.println(collect3);
//用逗号分隔每一个name字段,前后用【】
String collect4 = list.stream().map(User::getName)
.collect(Collectors.joining(",", "[", "]"));
System.out.println(collect4);//[张三,李四,王五,赵六,小黑]
String[]nums=new String[]{"1123","!23123","!@3123","12312"};
String collect9 = Arrays.stream(nums).collect(Collectors.joining());
System.out.println(collect9);
}
}