Java基础复习 Day 26
Stream
-
Stream的引入
对于Stream,是Java8的新特性,并不是之前学过的I/O流,而是通过对集合,数组等进行批量操作后从而简化以前对数组,集合复杂的计算。
-
传统集合的操作:发现总是在对集合进行循环遍历,或者各种数据的筛选操作时,对于批量数据来说,这种循环的方式显得比较效率低。
public static void main(String[] args) { List<String> strs = new ArrayList<>(); strs.add("KarenKou"); strs.add("Kyle"); strs.add("Steven"); strs.add("Kevin"); strs.add("Shelly"); strs.add("James"); //对集合中的元素进行遍历,把以K开头的名字储存在strsK中 List<String> strsK = new ArrayList<>(); for (String str: strs) { if (str.startsWith("K")){ strsK.add(str); } } //对集合中的元素再进行遍历,把strsK中的长度>5的名称给过滤掉,新数据存储在strsNew1中 List<String> strsNew1 = new ArrayList<>(); for (String str: strsK) { if(str.length()>5){ strsNew1.add(str); } } //遍历最新的集合,进行输出 for (String str: strsNew1) { System.out.println(str); } }
-
用Stream,专注于做什么,而不是怎么做,来进行遍历
public static void main(String[] args) { List<String> strs = new ArrayList<>(); strs.add("KarenKou"); strs.add("Kyle"); strs.add("Steven"); strs.add("Kevin"); strs.add("Shelly"); strs.add("James"); //用stream流的思想对集合中的元素进行遍历,把以K开头的名字储存在strsK中 Stream<String> strsk = strs.stream().filter((name) -> { return name.startsWith("K"); }); //对集合中的元素再进行遍历,把strsK中的长度>5的名称给过滤掉,新数据存储在strsNew1中 Stream<String> strsNew1 = strsk.filter((name) -> name.length() > 5); //遍历最新的集合,进行输出 strsNew1.forEach((name) -> System.out.println(name));//KarenKou //终极大法,链式编程 strs.stream().filter((name) -> name.startsWith("K")).filter((name) -> name.length()>5).forEach((name) -> System.out.println(name));//KarenKou }
-
-
Stream流式思想
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mYuKYKx6-1661334944861)(C:\Users\Karen\Desktop\MarkDown 学习\Java基础复习笔记\day26\Stream Model.png)]
这里的filter,map,skip都是在对函数模型来进行操作,集合元素并没有被真正处理,只有当终结方法count执行的时候,整个模型才会按照指定的策略来进行动作,
-
获取流
-
获取流的方式
java.util.stream.Stream<T>
是Java8新加入的最常用的stream流接口(但并不是函数式接口)获取流的方式有两种
-
所有的
Collection
集合都可以通过Stream
默认方法来获取流首先,
java.util.stream.Collection
接口中加入了default方法stream
来获取流,所以所有的Collection接口的实现类均可以通过此方法获取流default Stream<E> stream()
/** * Returns a sequential {@code Stream} with this collection as its source. * * <p>This method should be overridden when the {@link #spliterator()} * method cannot return a spliterator that is {@code IMMUTABLE}, * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()} * for details.) * * @implSpec * The default implementation creates a sequential {@code Stream} from the * collection's {@code Spliterator}. * * @return a sequential {@code Stream} over the elements in this collection * @since 1.8 */ default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }
-
/** * Returns a sequential {@code Stream} containing a single element. * * @param t the single element * @param <T> the type of stream elements * @return a singleton sequential stream */ public static<T> Stream<T> of(T t) { return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false); } /** * Returns a sequential ordered stream whose elements are the specified values. * * @param <T> the type of stream elements * @param values the elements of the new stream * @return the new stream */ @SafeVarargs @SuppressWarnings("varargs") // Creating a stream from an array is safe public static<T> Stream<T> of(T... values) { return Arrays.stream(values); }
-
public static void main(String[] args) { //把集合转换为Stream流 List<String> lists = new ArrayList<>(); lists.add("Karen"); lists.add("Kyle"); lists.add("Kate"); lists.add("Kevin"); Stream<String> stream1 = lists.stream(); Set<String> set = new HashSet<>(); Stream<String> stream2 = set.stream(); //对于双列集合,可以间接利用key值和获取值的set集合来获取流 Map<String,String> map = new HashMap<>(); //获取键 Set<String> keys = map.keySet(); Stream<String> stream3 = keys.stream(); //获取值 Collection<String> values = map.values(); Stream<String> stream4 = values.stream(); //或者获取键值对(键与值的对应关系) Set<Map.Entry<String, String>> entries = map.entrySet(); Stream<Map.Entry<String, String>> stream5 = entries.stream(); //把数组也可以获取流 通过Stream中的静态方法of Integer[] arrs = {1,2,3,4,5}; Stream<Integer> stream6 = Stream.of(arrs); }
-
-
-
逐一处理 forEach
void forEach(Consumer<? super T> action);
用来遍历流中的数据,逐一处理流元素的语句,该方法是一个终结方法,遍历之后不可再调用其他的流方法public static void main(String[] args) { Stream<String> stream1 = Stream.of("Karen", "Leonard", "Sheldon", "Kyle"); stream1.forEach((name) -> System.out.print(name + " "));//Karen Leonard Sheldon Kyle }
-
过滤:filter方法
Stream<T> filter(Predicate<? super T> predicate);
通过过滤形成一个新的不同的子流public static void main(String[] args) { Stream<String> stream1 = Stream.of("Karen", "Leonard", "Sheldon", "Kyle"); //对名字进行过滤,只要以K开头的名字 Stream<String> stream2 = stream1.filter((name) -> name.startsWith("K")); stream2.forEach((name)-> System.out.print(name + " "));//Karen Kyle }
-
Stream流的特点:Stream流式一个管道流,只能被消费(使用)一次,第一个Stream调用完方法时就会被关闭,数据流就会流向下一个Stream,此时再使用第一个stream调用方法时就会抛异常。
public static void main(String[] args) { Stream<String> stream1 = Stream.of("Karen", "Leonard", "Sheldon", "Kyle"); //对名字进行过滤,只要以K开头的名字 Stream<String> stream2 = stream1.filter((name) -> name.startsWith("K")); stream2.forEach((name)-> System.out.print(name + " "));//Karen Kyle stream1.forEach((name) -> System.out.println(name) );//抛异常 //Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed // at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279) // at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) // at com.kou.stream.demo1.DemoStreamMethod2.main(DemoStreamMethod2.java:11) }
-
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
public static void main(String[] args) { Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); //把Integer类型的stream转换成String类型的stream Stream<String> stream1 = stream.map((Integer a) -> a.toString()); stream1.forEach((str) -> System.out.println(str)); }
-
count方法
long count();
用来统计流中元素的个数 注意:返回值是long类型 并且该方法是终结方法public static void main(String[] args) { List<String> lists = new ArrayList<>(); lists.add("Karen"); lists.add("Kate"); lists.add("Kyle"); lists.add("Penny"); long count = lists.stream().count(); System.out.println(count); }
-
取用前几个:limit方法
Stream<T> limit(long maxSize);
对流进行截取,只截取前几个,参数是long型,如果当前集合的长度大于maxSize则截取,否则不进行操作。public static void main(String[] args) { List<String> lists = new ArrayList<>(); lists.add("Karen"); lists.add("Kate"); lists.add("Kyle"); lists.add("Penny"); //limit是一个延迟方法,所以仍然可以继续链式调用其他方法 lists.stream().limit(3).forEach(s -> System.out.print(s + ", "));//Karen, Kate, Kyle, }
-
跳过前几个:skip方法
Stream<T> skip(long n);
如果希望跳过前几个方法,可以通过使用skip方法来获取一个截取之后的新流如果当前的流的元素长度大于n,则跳过前n个,乳沟当前长度小于n,那么使用skip之后将会得到一个长度为0的空流
public static void main(String[] args) { List<String> lists = new ArrayList<>(); lists.add("Karen"); lists.add("Kate"); lists.add("Kyle"); lists.add("Penny"); //skip是一个延迟方法,所以仍然可以继续链式调用其他方法 lists.stream().skip(2).forEach((s -> System.out.print(s + " ")));//Kyle Penny }
-
组合方法:concat方法,如果希望将两个流合并为一个流,那么可以使用concat方法将两个流合并
注意:concat是
Stream
的静态方法 与String中的同名方法时不一样的。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)); }
public static void main(String[] args) { List<String> lists = new ArrayList<>(); lists.add("Karen"); lists.add("Kate"); lists.add("Kyle"); lists.add("Penny"); //skip是一个延迟方法,所以仍然可以继续链式调用其他方法 List<String> lists2 = new ArrayList<>(); lists.add("Sheldon"); lists.add("Leonard"); lists.add("Raji"); lists.add("Howard"); Stream<String> stream1 = lists.stream(); Stream<String> stream2 = lists2.stream(); Stream<String> stream3 = Stream.concat(stream1, stream2); stream3.forEach((s)-> System.out.print(s + " "));//Karen Kate Kyle Penny Sheldon Leonard Raji Howard }
-
Collection练习 使用传统方法和Stream流式的思想
-
传统方式 不停的for循环
public static void main(String[] args) { List<String> lists1 = new ArrayList<>(); List<String> lists11 = new ArrayList<>(); List<String> lists12 = new ArrayList<>(); lists1.add("Karen"); lists1.add("Kate"); lists1.add("Kyle"); lists1.add("Penny"); lists1.add("Kevin"); lists1.add("Karl"); for (String list : lists1) { if (list.length()==4) { lists11.add(list); } } for (int i = 0; i < 3; i++) { lists12.add(lists11.get(i)); } List<String> lists2 = new ArrayList<>(); List<String> lists21 = new ArrayList<>(); List<String> lists22 = new ArrayList<>(); List<String> listsNew = new ArrayList<>(); List<Person> persons = new ArrayList<>(); lists2.add("Sheldon"); lists2.add("Leonard"); lists2.add("Raji"); lists2.add("Hoaward"); lists2.add("Lucy"); lists2.add("Kate"); for (String list2: lists2) { if (list2.length()>4) { lists21.add(list2); } } for (int i = 2; i < lists21.size(); i++) { lists22.add(lists21.get(i)); } for (String s : lists12) { listsNew.add(s); } for (String s : lists22) { listsNew.add(s); } for (String s : listsNew) { persons.add(new Person(s)); } for (Person person : persons) { System.out.print(person + " "); //Person{name='Kate'} Person{name='Kyle'} Person{name='Karl'} Person{name='Hoaward'} } }
-
Stream流式思想
public static void main(String[] args) { List<String> lists1 = new ArrayList<>(); lists1.add("Karen"); lists1.add("Kate"); lists1.add("Kyle"); lists1.add("Penny"); lists1.add("Kevin"); lists1.add("Karl"); List<String> lists2 = new ArrayList<>(); lists2.add("Sheldon"); lists2.add("Leonard"); lists2.add("Raji"); lists2.add("Hoaward"); lists2.add("Lucy"); lists2.add("Kate"); Stream<String> stream1 = lists1.stream().filter((name) -> name.length() == 4).limit(3); Stream<String> stream2 = lists2.stream().filter((name) -> name.length() > 4).skip(2); Stream<String> stream3 = Stream.concat(stream1, stream2); //stream3.forEach((name) -> System.out.print(new Person(name) + " ")); //Person{name='Kate'} Person{name='Kyle'} Person{name='Karl'} Person{name='Hoaward'} //将string类型的stream转换成People类型的stream stream3.map((name) -> new Person(name)).forEach(person -> System.out.print(person + " ")); //Person{name='Kate'} Person{name='Kyle'} Person{name='Karl'} Person{name='Hoaward'} }
-
-
-
-
原文地址:https://www.jb51.cc/wenti/3281981.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。