Java高级编程—Stream流(从0到1详解,附有代码+案例)

Stream流

相当于把数据源加载到一条流水线上,即 在一条传输管道中对数据进行操作,

26.1 获取Stream流

获取方式方法名说明
单列集合default Stream stream()Collection中的默认方法
双列集合无法直接使用stream流
public static Stream stream(T[] array)Arrays工具类中的静态方法
一堆零散数据public static Stream of(T… values)Stream接口中的静态方法
双列集合  无Stream流   无法直接使用stream流
需要先把双列集合中数据转换成单列集合的数据

Stream流作用:结合Lambda表达式,简化集合、数组的操作。

import java.util.ArrayList;
import java.util.Collections;

public class Test {
    public static void main(String[] args) {
//单列集合==default Stream<E> stream() == Collection中的默认方法

        // 创建单列集合
        ArrayList<String> list = new ArrayList<>();
        // 添加元素给集合
        Collections.addAll(list,"a","b","c");

        // // 1.获取Stream流
        // Stream<String> stream1 = list.stream();
        // // 循环打印Stream流的每个元素
        // stream1.forEach(new Consumer<String>() {
        //    @Override
        //    public void accept(String s) {
        //       s:依次表示流水线上的每一个数据
        //        System.out.println(s);
        //    }
        // });


    // 2.获取Stream流并循环打印每个元素
    list.stream().forEach(s -> System.out.print(s+" "));
    //a b c


    }
}
import java.util.HashMap;

public class Test02 {
    public static void main(String[] args) {
//双列集合  无Stream流   无法直接使用stream流
// 需要先把双列集合中数据转换成单列集合的数据

        // 创建集合
        HashMap<String,Integer> map = new HashMap<>();
        // 添加数据
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);

        // 1.获取双列集合中所有的键,并放入单例集合中
        // 通过存放键的单例集合获取Stream流
      map.keySet().stream().forEach(s -> System.out.println(s));
      // a b c

        // 2.获取键值对 ,并放入单列集合中
        //通过存放键值对的单列集合获取Stream流
       //Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();
       // stream.forEach(s-> System.out.println(s));

     map.entrySet().stream().forEach(s-> System.out.println(s));
        //a=1  b=2  c=3
    }
}
import java.util.Arrays;
public class Test03 {
    public static void main(String[] args) {
//数组  public static <T> Stream<T> stream(T[] array)    Arrays工具类中的静态方法
        int[] arr1 = {1,2,3};
        String[] arr2 = {"你","好"};

   Arrays.stream(arr1).forEach(s-> System.out.println(s));
   //  1 2 3
   Arrays.stream(arr2).forEach(s -> System.out.println(s));
   //你 好
      
     // Stream接口中静态方法of的细节
     //方法的形参是一个可变参数,可以传递一堆零散数据,也可以传覅地数组
     //但是数组必须是引用数据类型
     //如果是基本数据类型,会把整个数组当作一个元素,放到Stream中
     Stream.of(arr1).forEach(s-> System.out.println(s));
     //[I@7ba4f24f
    Stream.of(arr2).forEach(s-> System.out.println(s));
     //你 好

    }
}
import java.util.stream.Stream;

public class Test04 {
    public static void main(String[] args) {
 //一堆零散数据   public static<T> Stream<T> of(T... values)  Stream接口中的静态方法

      Stream.of(1,2,3).forEach(s-> System.out.println(s));
      Stream.of("a","b").forEach(s-> System.out.println(s));

    }
}

26.2 Stream流中间方法

方法名说明
Stream filter(Predicate<? super T> predicate)过滤
Stream limit(long maxSize)获取前几个元素
Stream skip(long n)跳过前几个元素
Stream distinct()元素去重,依赖(hashCode和equals方法)
static Stream concat(Stream a,Stream b)合并a和b两个流为一个流
Stream map(Function<super T, R> mapper)转换流中的数据类型
1.中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
2.修改Stream流中的数据,不会影响原来集合或者数组中的数据
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
      //1.中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
     // 2:修改Stream流中的数据,不会影响原来集合或者数组中的数据

        // 创建集合
        ArrayList<String> list  = new ArrayList<>();
        ArrayList<String> list1 = new ArrayList<>();
        // 给集合添加元素
        Collections.addAll(list,"水果","水瓶","苹果","苹果");
        Collections.addAll(list1,"葡萄","西瓜");

        //1.filter   过滤
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                // true:留下当前元素;
                // false:当前元素舍弃
                return s.startsWith("水");
            }
        }).forEach(s-> System.out.println(s));//水果 水瓶

        list.stream().filter(s -> s.startsWith("水")).forEach(s -> System.out.println(s));
        //水果 水瓶

    //注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,
    // 建议使用链式编程
   // Stream<String> stream1 = list.stream().filter(s -> s.startsWith("水"));
        // Stream<String> stream2 = stream1.filter(s -> s.length() == 1);
        // stream1.filter(s -> s.length()==2);//此行运行时异常

        System.out.println();
        // 2.limit     获取前几个元素
        list.stream().limit(1).forEach(s -> System.out.println(s));
		 //水果
		       
		  //3. skip   跳过前几个元素
		 list.stream().skip(2).forEach(s -> System.out.println(s));
		  //苹果
		    
		// 4.distinct    元素去重,依赖(hashCode和equals方法)
		//distinct底层是利用HashSet去重的
		list.stream().distinct().forEach(s->System.out.println(s)); //水果  水瓶  苹果

          // 5.concat    合并a和b两个流为一个流
         Stream.concat(list.stream(),list1.stream()) .forEach(s -> System.out.println(s));
         //水果 水瓶  苹果 葡萄 西瓜
    }
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;

public class Test02 {
    public static void main(String[] args) {

        // 创建集合
        ArrayList<String> list  = new ArrayList<>();

        // 给集合添加元素
        Collections.addAll(list,"水果-1","水瓶-2","苹果-3");

        // map 转换流中的数据类型
        // 将String -> Integer
        //apply的形参s:依次表示流里面的每一个数据
        //返回值:表示转换之后的数据

        //当map方法执行完毕之后,流上的数据就变成了整数
        //所以在下面forEach当中,s依次表示流里面的每一个数据,
        //这个数据现在就是整数了

        //第一个类型:流中原本的数据类型
        //第二个类型:要转成之后的类型
        list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                String[] arr = s.split("-");
                String numString = arr[1];
                int i = Integer.parseInt(numString);
                return i;
            }
        }).forEach(s-> System.out.println(s));//1 2 3

         // 简化写法
        // map里的s表示流里的每一个数据:"水果-1","水瓶-2","苹果-3"
        // s.split("-"):表示一个数组:如:[水果, 1]....
        //s.split("-")[1]:数组里的第二个元素,类型为字符串
        list.stream()
                .map(s -> Integer.parseInt(s.split("-")[1]))
                .forEach(s-> System.out.println(s));

    }
}

26.3 Stream流终结方法(一)

方法名说明
void forEach(Consumer action)遍历
long count()统计
toArray()收集流中的数据,放到数组中
collection(Collection collection)收集流中数据,放到集合中
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.IntFunction;

public class Test03 {
    public static void main(String[] args) {
        
        // 创建集合
        ArrayList<String> list  = new ArrayList<>();

        // 给集合添加元素
        Collections.addAll(list,"水果-1","水瓶-2","苹果-3");

        // 1.遍历
        //Consumer的泛型:表示流中数据的类型
        //accept方法的形参s:依次表示流里面的每一个数据
        //方法体:对每一个数据的处理操作(打印)
          list.forEach(new Consumer<String>() {
              @Override
              public void accept(String s) {
                  System.out.println(s);
              }
          });

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

          // 2.统计
        long count = list.stream().count();
        System.out.println(count);//3

        // 3.收集
        Object[] obj = list.stream().toArray();
        String s = Arrays.toString(obj);
        System.out.println(s);//[水果-1, 水瓶-2, 苹果-3]

        //IntFunction的泛型:具体类型的数组
        //apply的形参:流中数据的个数,要跟数组的长度保持一致
        //apply的返回值:具体类型的数组
        //方法体:就是创建数组

        //toArray方法的参数的作用:负责创建一个指定类型的数组
        //toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
        //toArray方法的返回值:是一个装着流里面所有数据的数组
       String[] strArr = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(strArr));
        //[水果-1, 水瓶-2, 苹果-3]

    }
}

26.4 Stream流终结方法(二)

collect(Collector collector) 收集流中的数据,放到集合中 (List Set Map)

如果我们要收集到Map集合当中,键不能重复,否则会报错

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Test04 {
    public static void main(String[] args) {

        // 创建集合并添加数据
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张三-男-18","李四-男-19","小红-女-19");

        //收集List集合当中
        //需求:把所有的男性收集起来
        List<String> newlist1 = list.stream()
                //过滤性别为男的
                .filter(s -> "男".equals(s.split("-")[1]))
                // 收集过滤后性别为男的,并放入一个和集合中
                .collect(Collectors.toList());
        // 打印集合
        System.out.println(newlist1);//[张三-男-18, 李四-男-19]

        //收集Set集合当中
        //需求:我要把所有的男性收集起来
        Set<String> newlist2 = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toSet());
        System.out.println(newlist2);

        // 收集到Map集合中
        //谁作为键,谁作为值.
        //所有的男性收集起来
        //键:姓名。 值:年龄
        Map<String, Integer> map = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                /*
                 *   toMap : 参数一表示键的生成规则
                 *           参数二表示值的生成规则
                 *
                 * 参数一:
                 *    Function泛型一:表示流中每一个数据的类型
                 *             泛型二:表示Map集合中键的数据类型
                 *
                 *      方法apply形参:依次表示流里面的每一个数据
                 *               方法体:生成键的代码
                 *               返回值:已经生成的键
                 *
                 * 参数二:
                 *      Function泛型一:表示流中每一个数据的类型
                 *              泛型二:表示Map集合中值的数据类型
                 *
                 *       方法apply形参:依次表示流里面的每一个数据
                 *               方法体:生成值的代码
                 *               返回值:已经生成的值
                 * */
				.collect(Collectors.toMap(new Function<String, String>() {
				   @Override
				    public String apply(String s) {
				          return s.split("-")[0];
				                                   }
				                                       },
				      new Function<String, Integer>() {
				           @Override
				           public Integer apply(String s) {
				              return Integer.parseInt(s.split("-")[2]);
				                            }
				                        }
				                ));
			        System.out.println(map);//{李四=19, 张三=18}
			
			        // 简写
			        Map<String, String> map1 = list.stream()
			          .filter(s -> "男".equals(s.split("-")[1]))
			          .collect(Collectors.toMap(
			                    s -> s.split("-")[0],
			                    s -> s.split("-")[2]
			                ));
			        System.out.println(map1);//{李四=19, 张三=18}

// main ending.....
    }
}
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔚一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值