LongJL 发表于 2021-7-17 16:19

【自学笔记】 Java基础 - 流

# 流

## Stream流的三类方法
### 获取Stream流
- 创建一条流水线,并且把数据放到流水线上进行操作

### 中间方法
- 流水线上的操作。一次操作完毕之后,还可以继续进行其他操作。

### 终结方法
- 一条Stream流只能有一个终结方法,是流水线上的最后一个操作

## 使用Stream流的前提条件与方法
### 单列集合
#### 获取方法
可以使用Collection接口中的默认方法stream()生成流 `default Stream<E> stream()`
```Java
public class StreamDemo2 {
    public static void main(String[] args) {
      // 单列集合
      ArrayList<String> list = new ArrayList<>();

      list.add("aaa");
      list.add("bbb");
      list.add("ccc");

      list.stream().forEach(s-> System.out.println(s));
    }
}
```
### 双列集合
**间接**的生成流,可以先通过Keyset或者entrySet获取一个Set集合,在获取Steam流
```Java
public class StreamDemo2 {
    public static void main(String[] args) {
      // 双列集合
      HashMap<String,Integer> hm = new HashMap<>();

      hm.put("张三",23);
      hm.put("李四",24);
      hm.put("王五",25);
      hm.put("刘六",26);
      hm.put("琪琪",27);

      Set<String> set = hm.keySet();

      set.stream().forEach(s->{
            System.out.println(s + "====" + hm.get(s));
      });

      Set<Map.Entry<String, Integer>> entries = hm.entrySet();

      
      entries.stream().forEach((s)->{
            System.out.println(s);
      });
    }

}
```
### 数组
Arrays中的静态方法stream生成流
```Java
public class StreamDemo2 {
    public static void main(String[] args) {
      // 数组
      int[] arr = {1,2,3,4,5,6};

      Arrays.stream(arr).forEach(s->{
            System.out.println(s);
      });
    }
}
```
### 同种数据类型的多个数据
例如:1,2,3,4,5,6,或者"aaaa",bbb","ccc"
可以使用Stream.of(T...Values)生成流
```Java
public class StreamDemo2 {
    public static void main(String[] args) {
      // 同种数据类型的多个数据
      Stream.of(1,2,3,4,5,6,7,8,9,10).forEach(s->                                                         System.out.println(s));
    }
}

```
## 中间方法
- `Stream<T> filter(Predicate predicate)`:用户对流中的数据进行过滤
      Predicate接口中的方法
                `boolean test(T t)`:对给定的参数进行判断,返回一个布尔值
               
```Java
public class StreamDemo3 {
    public static void main(String[] args) {
      ArrayList<String> list = new ArrayList<>();

      list.add("张三丰");
      list.add("张无忌");
      list.add("张翠山");
      list.add("王麻子");
      list.add("张亮");
      list.add("谢霆锋");

      // filter方法获取流中的每一个数据
      // 而Test方法中的s,就依次表示流中的每一个数据
      // 只要在test方法中对s进行判断就可以了
      // 判断为true留下,false不要
//      list.stream().filter(new Predicate<String>() {
//            @Override
//            public boolean test(String s) {
//                return s.startsWith("张");
//            }
//      }).forEach(s -> System.out.println(s));
      
      // lambda
      
      list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));
    }
}
```

- `Stream<T> limit(long maxSize)`:截取指定参数个数的数据
- `Stream<T> skip(long n)`:跳过指定参数个数的数据
- `static<T> Stream<T> concat(String a,Stream b)`:合并a和b俩个流为一个流
- `Stream<T> distinct()`:去掉流中重复的元素。依赖(hashCode和equals方法)

```Java
public class StreamDemo4 {
    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("谢霆锋");

      ArrayList<String> list2 = new ArrayList<>();

      list.add("六六六");
      list.add("七七七七");
      list.add("八八八八八");

      // - `Stream<T> limit(long maxSize)`:截取指定参数个数的数据
      list.stream().limit(3).forEach(s -> System.out.println(s));
      System.out.println("++++++++++++++++++++++++++++");
      // - `Stream<T> skip(long n)`:跳过指定参数个数的数据
      list.stream().skip(3).forEach(s -> System.out.println(s));
      System.out.println("++++++++++++++++++++++++++++");
      // - `static<T> Stream<T> concat(String a,Stream b)`:合并a和b俩个流为一个流
      Stream.concat(list.stream(),list2.stream()).forEach(s-> System.out.println(s));
      System.out.println("++++++++++++++++++++++++++++");
      // - `Stream<T> distinct()`:去掉流中重复的元素。依赖(hashCode和equals方法)
      list.stream().distinct().forEach(s -> System.out.println(s));
    }
}

```

## 终结方法
- `void forEach(Consumer aciton)`:对此流的每一个元素执行操作
      Consumer接口中的方法:`void accept(T t)`:对给定的参数执行此操作
- `long count()`:返回此流中的元素个数

```Java
public class StreamDemo5 {
    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("谢霆锋");

      // `void forEach(Consumer aciton)`:对此流的每一个元素执行操作

      // 在forEach方法的底层中,会循环获取到流中的每一个数据,
      // 并循环调用accept方法,并把每一个数据传递给accept方法
      // s就依次表示流中的每一个数据
      // 所有,只要在accept方法中,写上处理的业务逻辑就行了
      list.stream().forEach(
                new Consumer<String>() {
                  @Override
                  public void accept(String s) {
                        System.out.println(s);
                  }
                }
      );

      list.stream().forEach(s -> System.out.println(s));

      // `long count()`:返回此流中的元素个数
      long count = list.stream().count();
      System.out.println(count);
    }
}
```


## Stream流的收集操作
- 在Stream流中无法直接修改集合,数组等数据源中的数据。

### 方法
- R collect(Collector collector)

### 工具类Collectors提供了集体的收集方式
- `public static<T> Collector toList()`:把元素收集到List集合中
- `public static<T> Collector toSet()`:把元素收集到Set集合中
- `public static Collector toMap(Function keyMapper,Function valueMapper)`:把元素收集到Map集合中

```Java
public class StreamDemo7 {
    public static void main(String[] args) {
      ArrayList<Integer> list = new ArrayList<>();
      for (int i = 1; i <=10; i++) {
            list.add(i);
      }

      // filter 负责过滤数据
      // collect负责收集数据 但是他不负责创建容器,也不负责把数据添加到容器中
      // Collectors.toList():在底层会创建一个List集合,并把所有的数据添加到List集合中
      List<Integer> collect = list.stream().filter(integer -> integer % 2 == 0).collect(Collectors.toList());
      System.out.println(collect);

      Set<Integer> collect1 = list.stream().filter(integer -> integer % 2 == 0).collect(Collectors.toSet());
      System.out.println(collect1);
    }
}
```


```Java
public class StreamDemo8 {
    public static void main(String[] args) {
      ArrayList<String> list = new ArrayList<>();
      list.add("zhangsan,23");
      list.add("lisi,24");
      list.add("wangwu,25");


      Map<String, Integer> collect = list.stream().filter(s -> {
            String s1 = s.split(",");
            return Integer.parseInt(s1) >= 24;
      }).collect(Collectors.toMap(s -> s.split(","), s -> Integer.parseInt(s.split(","))));

      Set<Map.Entry<String, Integer>> entries = collect.entrySet();
      for (Map.Entry<String, Integer> entry : entries) {
            System.out.println(entry);
      }
    }
}
```

clevermoon 发表于 2021-7-17 16:31

认真地学习java

Vn丶兮 发表于 2021-7-17 18:26

在这里还能学习JAVA,楼主可以写博客

LongJL 发表于 2021-7-17 18:55

Vn丶兮 发表于 2021-7-17 18:26
在这里还能学习JAVA,楼主可以写博客

{:301_998:}博客 后面再说了

Su_y 发表于 2021-7-17 22:01

阔以,学习一下

shenme13 发表于 2021-7-17 22:08

学习了,感谢分享

bozai008 发表于 2021-7-17 22:30

学习了,谢谢

tomcar 发表于 2021-7-25 19:34

我以为是io流。。。

LongJL 发表于 2021-7-26 07:48

tomcar 发表于 2021-7-25 19:34
我以为是io流。。。

IO在后面

shanghai337 发表于 2021-7-26 14:00

添砖java
页: [1] 2
查看完整版本: 【自学笔记】 Java基础 - 流