八 JDK8新特性——第三节 两种获取Stream流的方式

1、两种获取Stream流的方式

java.util.stream.Stream<T> 是java 8 加入的最常用的流接口,这并不是一个函数式接口
获取流两种方式:
1、所有Collection 集合(单列集合)都可以通过stream默认方式获取流
default Stream<E> stream()
2、Stream接口的静态方法of可以获取数组对应的流
static <T> Stream<T> of (T... values)
参数是一个可变参数,就可传递一个数组

package con.day13.demo05.StreamAndMethod.Stream;

import java.util.*;
import java.util.stream.Stream;

/*
两种方式获取流
1、Collection 接口中的方法stream()
2、Stream接口的静态方法of:返回单个元素的序列Stream
static <T> Stream<T> of (T... values)
参数是一个可变参数,可传递一个数组
 */
public class Demo02GetStream {
    public static void main(String[] args) {
        //把单列集合转换成Stream
        List<String> list = new ArrayList();
        Stream<String> stream = list.stream();

        //Set
        Set<String> set = new HashSet<>();
        Stream<String> stream1 = set.stream();

        Map<String,String> map1 = new HashMap<>();
        Set<String> strings = map1.keySet();
        Stream<String> stream2 = strings.stream();

        Collection<String> values = map1.values();
        Stream<String> stream3 = values.stream();

        Set<Map.Entry<String, String>> entries = map1.entrySet();
        Stream<Map.Entry<String, String>> stream4 = entries.stream();

        //把数组转换成Stream流
        Stream<Integer> stream5 = Stream.of(1, 2, 34, 4);  //可变参数

        //可变参数可以传数组
        int[] arr = {1,3,4,5};
        Stream<int[]> stream6 = Stream.of(arr);

        String[] arr2 = {"a","fff","fs"};
        Stream<String> stream7 = Stream.of(arr2);
    }
}

2、Stream 流中的常用方法-forEach

常用方法
forEach
package con.day13.demo05.StreamAndMethod.Stream;

import java.util.stream.Stream;

/*
void forEach(Consumer<? super T> action);
该方法接收一个Consumer函数接口,会将每一个流元素交给该函数进行处理
Consumer 是一个消费性的函数式接口,可以传递Lambda表达式
注意:
for each 用来遍历流中的数据
是终结方法, 遍历之后不能调用Stream流中的其他方法

 */
public class Demo02Streamfor {
    public static void main(String[] args) {
        Stream<String> af = Stream.of("af", "sdkf", "cc", "gg", "hh");
       /* af.forEach((String name)->{
            System.out.println(name);
        });*/

        //简化Lambda表达式
        System.out.println("--------");
        af.forEach((name)-> System.out.println(name));
    }
}

结果
 af
sdkf
cc
gg
hh

3、Stream 流中的常用方法-filter

filter
package con.day13.demo05.StreamAndMethod.Stream;

import java.util.stream.Stream;

public class Demo02StreamFilter {
    public static void main(String[] args) {
        //创建Stream 流
        Stream<String> stream = Stream.of("张三丰", "张无极", "张强", "赵敏", "周芷若");
        //对Stream 流中的元素进行过滤,只要姓张的, 得到一个新的流, 接收他
        Stream<String> stream2 =  stream.filter((String name )->{ return name.startsWith("张");});
        stream2.forEach((name)-> System.out.println(name));
    }
}

4、Stream 流的特点,只能使用一次

Stream流属于管道流,只能被使用一次
第一个Stream流调用完毕方法,数据就会流转到下一个Stream 上
而这时第一个Stream流已经使用完毕,就会关闭了
所以第一个Streaml流就不能再调用方法了

package con.day13.demo05.StreamAndMethod.Stream;

import java.util.stream.Stream;

public class Demo02StreamFilter {
    public static void main(String[] args) {
        //创建Stream 流
        Stream<String> stream = Stream.of("张三丰", "张无极", "张强", "赵敏", "周芷若");
        //对Stream 流中的元素进行过滤,只要姓张的, 得到一个新的流, 接收他
        Stream<String> stream2 =  stream.filter((String name )->{ return name.startsWith("张");});
        stream2.forEach((name)-> System.out.println(name));

        stream.forEach((name)-> System.out.println(name));  //报错,
        //Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
    }
}

结果
张三丰
张无极
张强
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 con.day13.demo05.StreamAndMethod.Stream.Demo02StreamFilter.main(Demo02StreamFilter.java:13)

5、Stream 流中的常用方法-map

map映射
package con.day13.demo05.StreamAndMethod.Stream;

import java.util.stream.Stream;

public class Demo02StreamMap {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("1", "2", "3", "4");
        Stream<Integer> integerStream = stream.map((s) -> Integer.parseInt(s));

        integerStream.forEach(i-> System.out.println(i));

    }
}
结果
1
2
3
4

6、Stream 流中的常用方法-count

count
package con.day13.demo05.StreamAndMethod.Stream;

import java.util.ArrayList;
import java.util.stream.Stream;

//统计流中元素的个数, 返回值是long类型的整数,是一个终结方法,不能再调用Stream中其他方法
public class Demo02StreamCount {
    public static void main(String[] args) {
        Stream<String> a = Stream.of("a", "b", "d");
        System.out.println(a.count());

        ArrayList<String> list = new ArrayList<>();
        list.add("22");
        list.add("4");
        list.add("7");

        Stream<String> stream2 = list.stream();
        long count = stream2.count();
        System.out.println(count);
    }
}

3 
3

7、Stream 流中的常用方法-limit

limit 是一个延迟方法, 对流中元素截取,返回一个新的流,可以调用流中其他方法


limit
package con.day13.demo05.StreamAndMethod.Stream;

import java.util.stream.Stream;

public class Demo02StreamLimit {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("44", "fsdf", "t", "9", "2", "iu");
        Stream<String> limit = stream.limit(4);
       // System.out.println(limit.count());  //4
        limit.forEach(s-> System.out.println(s));
    }
}

}

结果
44
fsdf
t
9

8、Stream 流中的常用方法-skip

skip
package con.day13.demo05.StreamAndMethod.Stream;

import java.util.Arrays;
import java.util.stream.Stream;

public class Demo02StreamSkip {
    public static void main(String[] args) {
        String[] arr  = {"sdf","fsd","wr","il"};
        Stream<String> stream = Stream.of(arr);
//跳过前三个元素
        Stream<String> skip = stream.skip(3);
      //  System.out.println(skip.count());   1
//遍历新的流
        skip.forEach(s -> System.out.println(s));  //il
    }
}

9、Stream 流中的常用方法-concat

concat
package con.day13.demo05.StreamAndMethod.Stream;

import java.util.stream.Stream;

public class Demo02StreamConcat {
    public static void main(String[] args) {
        String[] arr  = {"sdf","fsd","wr","il"};
        Stream<String> stream = Stream.of(arr);

        String[] arr2  = {"tyui","rg","ghj","ghj"};
        Stream<String> stream2 = Stream.of(arr);

        Stream<String> concat1 = Stream.concat(stream, stream2);
        concat1.forEach(e-> System.out.println(e));
    }
}

结果
sdf
fsd
wr
il
sdf
fsd
wr
il

10、练习,集合元素处理,传统方式

题目

import java.util.ArrayList;

public class DemoArrayList {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张无忌");
        list1.add("黑色裤");
        list1.add("迪丽热巴");
        list1.add("古力扎");
        list1.add("张收到回复");
        list1.add("胡返回");

        //只要名字为3个字的成员,储存到新集合中
        ArrayList<String> list11 = new ArrayList<>();
        for (String s : list1) {

            if (s.length() == 3){
                list11.add(s);
            }
        }


        //只要前三个人
        ArrayList<String> list12 = new ArrayList<>();


        for (int i = 0; i < 3; i++) {
            list12.add(list11.get(i)); //i = 0 1 2
        }



        ArrayList<String> list2 = new ArrayList<>();
        list2.add("张三丰");
        list2.add("张三好");
        list2.add("张三符");
        list2.add("王三看");
        list2.add("张三与");
        list2.add("杨三与");

        //只要姓张的
        ArrayList<String> list21 = new ArrayList<>();
        for (String s2 : list2) {
            //只要姓张的成员
            if (s2.startsWith("张")) {
                list21.add(s2);
            }
            }

        //不要前两个
        ArrayList<String> list22 = new ArrayList<>();
        for (int i = 2; i < list21.size(); i++) {
            list22.add(list21.get(i)) ; //2 - length
        }

        //5、将两个队伍合并成一个队伍,存储到一个新的集合中
        ArrayList<String> all = new ArrayList<>();
        all.addAll(list12);
        all.addAll(list22);

        //6、根据姓名创建Person对象,存储到一个新集合中
        ArrayList<Person> list = new ArrayList<>();

        for (String s : all) {
            list.add(new Person(s));
        }

        //7、打印整个队伍的Person
        for (Person person : list) {
            System.out.println(person);
        }

        }
    }

结果
Person{name='张无忌'}
Person{name='黑色裤'}
Person{name='古力扎'}
Person{name='张三符'}
Person{name='张三与'}

11、练习,集合元素处理, Stream 流处理

package con.day13.demo05.StreamAndMethod.Lianxi;

import java.util.ArrayList;
import java.util.stream.Stream;

public class DemoStream01 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张无忌");
        list1.add("黑色裤");
        list1.add("迪丽热巴");
        list1.add("古力扎");
        list1.add("张收到回复");
        list1.add("胡返回");

        Stream<String> oneStream = list1.stream().filter(name->name.length() == 3).limit(3);


        ArrayList<String> list2 = new ArrayList<>();
        list2.add("张三丰");
        list2.add("张三好");
        list2.add("张三符");
        list2.add("王三看");
        list2.add("张三与");
        list2.add("杨三与");

        Stream<String> twoStream = list2.stream().filter(name->name.startsWith("张")).skip(2);

       Stream.concat(oneStream, twoStream).map(name -> new Person(name)).forEach(p-> System.out.println(p));
//简写
       Stream.concat(oneStream, twoStream).map(Person::new).forEach(System.out::println);

    }
}

结果
Person{name='张无忌'}
Person{name='黑色裤'}
Person{name='古力扎'}
Person{name='张三符'}
Person{name='张三与'}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容