什么是Stream流
Stream不是集合元素,不是数据结构,因此不能保存数据。Stream只需给出需要对其包含的元素执行什么操作(如过滤长度符合指定长度的字符串等),Stream会隐式地在内部进行遍历,做出相应的数据转换,相当于数据在流水线上进行加工,加工后得到我们想要的数据。
几种常用的函数式接口
开始学习Stream流之前,我们需要了解几种常用的函数式接口:
- Function函数式接口
/**
* Function
*有参数,有返回值
*/
public static void main(String[] args) {
Function function = new Function<String, String>() {
@Override
public String apply(String str) {
return str;
}
};
//使用Lambda表达式简化
Function<String, String> function2 = (str) -> {return str; };
System.out.println(function2.apply("asd"));
}
- Predicate 接口
/**
* Predicate
*有一个输入参数,返回值只能是boolean值,用于做判断
*/
public static void main(String[] args) {
//可以来做判断字符串是否为空
Predicate pc = new Predicate<String>() {
@Override
public boolean test(String str) {
return str.isEmpty();
}
};
System.out.println(pc.test("qwew"));
//Lambda简化
Predicate<String> pre =(str)->{return str.isEmpty(); };
System.out.println(pre.test(""));
}
- Customer消费型接口
/**
* 消费型接口
*/
public class ConsumerInterface {
public static void main(String[] args) {
Consumer<String> stringConsumer = new Consumer<String>() {
@Override
public void accept(String str) {
System.out.println(str);
}
};
//简化
Consumer<String> consumer =(str)->{System.out.println(str);};
consumer.accept("打印str");
}
}
- Supplier供给型接口
/**
* 供给型接口
*/
public class SupplierInterface {
public static void main(String[] args) {
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return "供给型接口";
}
};
//简化
Supplier<String> sp =()->{return "供给型接口";};
System.out.println(sp.get());
}
获取Stream流的方式
- 通过Collection接口中的stream()方法获取Stream流
public interface Collection<E> extends Iterable<E> {
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
ArrayList<Integer> list = new ArrayList<>();
Stream<Integer> stream = list.stream();
- 通过Stream接口中的of()静态方法获取Stream流
public interface Stream<T> extends BaseStream<T, Stream<T>> {
@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
}
Stream<String> stream = Stream.of("a","b","c","d","e");
Stream常用的API
- Stream中方法的两种分类
- 终结方法,如count()、forEach()方法,如果不在最后调用Stream的终结方法,那么中间的其他非终结方法不会执行。
- 非终结方法(函数拼接方法),如filter()方法,非终结方法返回的是新的Stream流。
::
双冒号的用法
::
双冒号的作用是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下,双冒号运算就是Java中的方法引用,其格式是为:类名::方法名
- 如将Role实体类映射为name,在没有使用::双冒号的情况下:
stream().map((Role)->{return Role.getName();})
- 使用双冒号后
stream().map(Role::getName})
- 又如在Stream流中的forEeach遍历输出流中 的字符,在没有使用双冒好的情况下为:
list.stream().forEach((str)->{
System.out.println(str);
});
- 使用后如下:
list.stream().forEach(System.out::println);
forEach()
forEach()方法遍历流中的元素
void forEach(Consumer<? super T> action);
Example:
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.stream().forEach((str)->{
System.out.println(str);
});
//简写
list.stream().forEach(System.out::println);
count()
count()方法计算流中的元素长度
long count();
filter()
筛选过滤出符合指定条件的元素
Stream<T> filter(Predicate<? super T> predicate);
Example:
//筛选出值为a的元素
list.stream().filter((str)->{
return str.equals("a");
}).forEach(System.out::println);
limit(long n)
从流中筛选出前n个元素
Stream<T> limit(long maxSize);
Example:
//筛选出流中前两个元素
list.stream().limit(2).forEach(System.out::println);
skip()
skip()方法跳过前面n个元素,获取下标为n后的元素组成的新流,如果n为0,则不会改变流中的元素个数,如果原始流中有a,b,c,d 4个元素,当n取1时,则返回包含b,c,d 3个元素的新流。
Stream<T> skip(long n);
Example:
list.stream().skip(1).forEach(System.out::println);
map()
map()方法,将流中的元素映射到另外一个流中
//该方法需要一个Function型函数式接口,将当前流中T类型的数据转换成R类型的流
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Example:
public class User {
private String name;
private int age;
private int id;
}
User u1 = new User("a", 11, 1);
User u2 = new User("b", 12, 2);
User u3 = new User("c", 24, 12);
User u4 = new User("d", 34, 4);
List<User> users = Arrays.asList(u1, u2, u3, u4);
users.stream().map((u)->{
return u.getName()+u.getAge();
}).forEach(System.out::println);
输出:
a11
b12
c24
d34
(2)将原本流中类型为String的数据转换成整型数据
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.stream().map((str)->{
return Integer.parseInt(str);
}).forEach(System.out::print);
flatMap()
flatMap()*方法,对流进行扁平化
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
Example:
String[] string = {"a","b","c","d"};
list.stream().flatMap((str)-> Arrays.stream(string)).forEach(System.out::print);
输出:
abcd abcd abcd abcd
sorted()
sorted()方法,对流中的数据进行排序
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}
Example:
List<Integer> list = new ArrayList<>();
list.add(13);
list.add(12);
list.add(8);
list.add(4);
list.stream().sorted((str1,str2)->(str1-str2)).forEach(System.out::println);
distinct()
distinct()方法,去除重复数据
Stream<T> distinct();
Example:
List<Integer> list = new ArrayList<>();
list.add(13);
list.add(12);
list.add(12);
list.add(8);
list.add(4);
list.add(4);
list.stream().distinct().forEach(System.out::println);
输出:
13
12
8
4
allMatch()、anyMatch()、nonMatch()
allMatch()、anyMatch()、nonMatch()方法,判断数据是否匹配指定条件
//allMatch():元素是否全部都匹配条件
boolean allMatch(Predicate<? super T> predicate);
//anyMatch():元素是否有任意一个匹配条件
boolean anyMatch(Predicate<? super T> predicate);
//nonMatch():元素是否全部都不满足条件
boolean noneMatch(Predicate<? super T> predicate);
Example:
List<Integer> list = new ArrayList<>();
list.add(13);
list.add(12);
list.add(8);
list.add(4);
boolean b1 = list.stream().allMatch((n) -> {return n > 8;});//false
boolean b2 = list.stream().anyMatch((n) -> {return n > 8;});//true
boolean b3 = list.stream().noneMatch((n) -> {return n > 8;});//false
findFirst()
findFirst()方法,获取流中的第一个元素
Optional<T> findFirst();
Example:
List<Integer> list = new ArrayList<>();
list.add(13);
list.add(12);
list.add(8);
list.add(4);
Optional<Integer> first = list.stream().findFirst();
System.out.println(first.get()); //13
findAny()
findAny()方法,返回流中随机任意一个元素
Optional<T> findAny();
Example:
List<Integer> list = new ArrayList<>();
list.add(12);
list.add(8);
list.add(4);
list.add(13);
Optional<Integer> any = list.stream().findAny();
System.out.println(any.get());
max()、min()
max()、min()方法,获取流中最大、最小的元素
Optional<T> max(Comparator<? super T> comparator);
Optional<T> min(Comparator<? super T> comparator);
Example:
List<Integer> list = new ArrayList<>();
list.add(12);
list.add(8);
list.add(4);
list.add(13);
Optional<Integer> max = list.stream().max((n1, n2) -> {
return n1 - n2;
});
Optional<Integer> min = list.stream().min((n1, n2) -> {
return n1 - n2;
});
System.out.println(max.get()); //13
System.out.println(min.get()); //4
reduce()
reduce()方法,将所有数据归纳得到一个总的数据
/**
* T identity :默认值
* BinaryOperator<T> accumulator 归纳数据的处理方式
**/
T reduce(T identity, BinaryOperator<T> accumulator);
//reduce()方法的第二个参数
public interface BinaryOperator<T> extends BiFunction<T,T,T> {}
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
}
Example:
List<Integer> list = new ArrayList<>();
list.add(12);
list.add(8);
list.add(4);
list.add(13);
Integer reduce = list.stream().reduce(0, new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer+integer2;
}
});
//以上简化得下
Integer reduce = list.stream().reduce(0, (n1, n2) -> {
return n1 + n2;
});
System.out.println(reduce); // 37 = 12 + 8 + 4 + 13
mapToInt()
mapToInt()方法,将Stream流中的Integer类型的元素转换成int类型
IntStream mapToInt(ToIntFunction<? super T> mapper);
Example:
List<Integer> list = new ArrayList<>();
list.add(12);
list.add(8);
list.add(4);
list.add(13);
list.stream().mapToInt(new ToIntFunction<Integer>() {
@Override
public int applyAsInt(Integer value) {
return value;
}
}).forEach(System.out::println);
concat()
concat()方法,Stream接口中的静态方法,合并两个流
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
@SuppressWarnings("unchecked")
Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>(
(Spliterator<T>) a.spliterator(), (Spliterator<T>) b.spliterator());
Stream<T> stream = StreamSupport.stream(split, a.isParallel() || b.isParallel());
return stream.onClose(Streams.composedClose(a, b));
}
Example:
List<Integer> list = new ArrayList<>();
list.add(12);
list.add(8);
list.add(4);
list.add(13);
Stream<Integer> stream1 = list.stream().filter((str) -> {
return str > 12;
});
Stream<Integer> stream2 = list.stream().filter((str) -> {
return str < 5;
});
Stream.concat(stream1, stream2).forEach(System.out::println); //13 4
🏁以上就是对JDK8新特性Stream流的详细解释,如果有错误的地方,还请留言指正,如果觉得本文对你有帮助那就点个赞👍吧😋😻😍