The road is long,it can be really hard.Whatever you do,you hold on to that foolishly hopeful smile
—— 24.6.19
Stream流
stream流中的"流"不是特指"IO流",它是一种"流式编程"(编程方式),可以看做是"流水线
package S109Stream;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Demo312Stream {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张三丰");
list.add("张大彪");
list.add("吕不韦");
list.add("张三");
list.add("赵姬");
list.add("张翠山");
list.add("缪毒");
/*
方式1:
// 需求1:要筛选出姓张的人
ArrayList<String> listZhang = new ArrayList<>();
for (String s : list) {
if (s.startsWith("张")) {
listZhang.add(s);
}
}
System.out.println(listZhang);
// 需求2:筛选出姓张、姓名三个字的人
ArrayList<String> listThrZhang = new ArrayList<>();
for (String s : list) {
if (s.startsWith("张")&&s.length()==3){
listThrZhang.add(s);
}
}
System.out.println(listThrZhang);
// 需求3:遍历集合,将三个字姓张的打印出来
for (String s : listThrZhang) {
System.out.println(s);
}
*/
// 方式2:将list转成stream流对象
Stream<String> stream = list.stream();
/*
stream.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张");
}
}).filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length()==3;
}
}).forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
*/
// 方式3:将list转成stream流对象,并用lambda表达式输出
System.out.println("——————————————Lambda表达式——————————————");
stream.filter(s -> s.startsWith("张")).filter(s -> s.length()==3).forEach(s -> System.out.println(s));
}
}
1.Stream的获取
① 针对集合:Collection中的方法
Stream<E> stream()
② 针对数组:Stream接口中的静态方法
Static <T> Stream<T> of(T...values)
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo313StreamGet {
public static void main(String[] args) {
// ① 针对集合:Collection中的方法
// Stream<E> stream()
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
Stream<String> stream = list.stream();
System.out.println(stream); // 地址值:java.util.stream.ReferencePipeline$Head@7f31245a
// ② 针对数组:Stream接口中的静态方法
// Static <T> Stream<T> of(T...values)
Stream<String> stream1 = Stream.of("张三","李四","王五");
System.out.println(stream1); // java.util.stream.ReferencePipeline$Head@6d6f6e28
}
}
2.Stream中的方法
① forEach方法:
void forEach(Consumer<? super T> action);
注意:forEach是一个终结方法(运行结束会自动关闭流)
import java.util.function.Consumer;
import java.util.stream.Stream;
public class Demo314StreamForeach {
public static void main(String[] args) {
foreach();
}
/**
* 逐一处理,可以用来遍历
*/
private static void foreach() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五");
// stream1.forEach(new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);
// }
// });
System.out.println("—————————————Lambda表达式—————————————");
stream1.forEach(s -> System.out.println(s));
}
}
② long count()方法
1.作用:统计元素个数
2.注意:count也是一个终结方法
import java.util.stream.Stream;
public class Demo315StreamCount {
public static void main(String[] args) {
count();
}
/**
* 统计元素个数
*/
private static void count() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五", "赵六");
long count = stream1.count();
System.out.println(count);
}
}
③ Stream<T> filter(Predicate<? super T>predicate)方法
1.方法:stream<T> filter(Predicate<? super T> predicate)方法,返回一个新的stream流对象
2.作用:根据某个条件进行元素过滤
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Demo316StreamFilter {
public static void main(String[] args) {
filter();
filter2();
}
private static void filter2() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五", "赵六","马七","张晓梅","马冬梅");
System.out.println("——————————————————lembda表达式————————————————");
stream1.filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
}
private static void filter() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五", "赵六","马七","张晓梅","马冬梅");
Stream<String> newStream = stream1.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length() == 3;
}
});
newStream.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
}
}
④ Stream<T> limit(long maxsize)方法
获取Stream流对象中的前n个元素,返回一个新的Stream流对象
import java.util.stream.Stream;
public class Demo317StreamLimit {
public static void main(String[] args) {
limit();
}
/**
* 获取前几个元素
*/
private static void limit() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五", "赵六","马七","张晓梅","马冬梅");
stream1.limit(3).forEach(s-> System.out.println(s));
}
}
⑤ Stream<T> skip(long n)
跳过stream流对象中的前n个元素,返回一个新的Stream流对象
import java.util.stream.Stream;
public class Demo318StreamSkip {
public static void main(String[] args) {
skip();
}
/**
* 跳过前n个元素
*/
private static void skip() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五", "赵六","马七","张晓梅","马冬梅");
stream1.skip(2).forEach(s-> System.out.print(s+" "));
}
}
⑥ static<T> Stream<T> concat(Stream<? extends T> a, Stream<?extends T> b)
两个流合成一个流
import java.util.stream.Stream;
public class Demo319StreamConcat {
public static void main(String[] args) {
Concat();
}
/**
* 流合并,是一个静态方法
*/
private static void Concat() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五");
Stream<String> stream2 = Stream.of("赵六","马七","张晓梅","马冬梅");
Stream<String> stream3 = Stream.concat(stream1, stream2);
stream3.forEach(s -> System.out.print(s+" "));
}
}
⑦ 将Stream流变成集合
从stream流对象转成集合对象,使用stream接口方法collect()
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo320StreamCollect {
public static void main(String[] args) {
Collect();
Collect1();
}
/**
* 流转集合
*/
private static void Collect1() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五", "赵六","马七","张晓梅","马冬梅");
List<String> collect1 = stream1.collect(Collectors.toList());
System.out.println(collect1);
}
private static void Collect() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五", "赵六","马七","张晓梅","马冬梅");
Set<String> collect = stream1.collect(Collectors.toSet());
System.out.println(collect);
}
}
⑧ distinct方法
Stream<T> distinct()
元素去重复,依赖hashcode和equals方法
Person类
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
import java.util.stream.Stream;
public class Demo321StreamDistinct {
public static void main(String[] args) {
distinct();
}
/**
* 去重复元素的
* 被去重的元素底层需要重写hashcode和equals方法
*/
private static void distinct() {
Stream<String> stream1 = Stream.of("张三", "李四", "王五", "张三","张晓梅","赵六","马七","张晓梅","马冬梅");
stream1.distinct().forEach(s->System.out.print(s+" "));
System.out.println();
Stream<Person> stream2 = Stream.of(new Person("张三",10),new Person("李四",12),new Person("张三",10));
stream2.distinct().forEach(person->System.out.print(person+" "));
}
}
⑨ 转换流中的类型
Stream<R> map(Function<T,R> mapper) —> 转换流中的数据类型
import java.util.function.Function;
import java.util.stream.Stream;
public class Demo322StreamMap {
public static void main(String[] args) {
map();
}
/**
* 转换流中的类型
*/
private static void map() {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
stream.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) {
return integer.toString();
}
}).forEach(s -> System.out.println(s+1));
}
}
⑩ Stream流练习
1.第一个队伍只要名字为3个字的成员姓名;——filter
2.第一个队伍筛选之后只要前3个人;——limit
3.第二个队伍只要姓张的成员姓名;——filter
4.第二个队伍筛选之后不要前2个人;——skip
5.将两个队伍合并为一个队伍;——concat
6.打印整个队伍的姓名信息。——forEach
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo323StreamPractice {
public static void main(String[] args) {
ArrayList<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老于");
one.add("庄于");
one.add("孙子");
one.add("洪七公");
ArrayList<String> two =new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("张三丰");
two.add("赵丽颖");
two.add("张二狗");
two.add("张天爱");
two.add("张三");
// 将两个集合变成Stream流
Stream<String> teamA = one.stream();
Stream<String> teamB = two.stream();
/**
* 1.第一个队伍只要名字为3个字的成员姓名;——filter
* 2.第一个队伍筛选之后只要前3个人;——limit
* 3.第二个队伍只要姓张的成员姓名;——filter
* 4.第二个队伍筛选之后不要前2个人;——skip
* 5.将两个队伍合并为一个队伍;——concat
* 6.打印整个队伍的姓名信息。——forEach
*/
Stream<String> listA = teamA.filter(s -> s.length() == 3).limit(3);
Stream<String> listB = teamB.filter(s -> s.startsWith("张")).skip(2);
Stream.concat(listA, listB).forEach(s -> System.out.println(s));
}
}