JDK8 Stream 初识

11 篇文章 0 订阅
9 篇文章 0 订阅

点这里
Stream作为jdk8的一种重要特性,我们应该了解多一些。

为什么会有Stream?

在Stream出现之前,我们对集合中的元素进行一些操作需要先遍历每个元素再进行操作。如:

	  LinkedHashMap<String, Integer> linkedHashMap =  new LinkedHashMap<String, Integer>();
	  linkedHashMap.put("1", 1);
	  linkedHashMap.put("2", 2);
	  linkedHashMap.put("3", 3);
	  linkedHashMap.put("4", 4);
	  LinkedHashMap<String, Integer> linkedHashMap2 =  new LinkedHashMap<String, Integer>();	  
	  for (Entry entry : linkedHashMap.entrySet()) {
		  int v = (int)entry.getValue();
		linkedHashMap2.put((String)entry.getKey(), v*2);
	}
	//结果:
	//[1=1, 2=2, 3=3, 4=4]
	//[1=2, 2=4, 3=6, 4=8]

在1.8我们怎么实现呢?

HashMap<String, Integer> hashMap = (HashMap<String, Integer>) linkedHashMap
				.entrySet()
				.stream()
				.collect(
						Collectors.toMap(a -> a.getKey(), a -> a.getValue() * 2));
System.out.println(hashMap.entrySet());
//[1=2, 2=4, 3=6, 4=8]

当你熟练掌握stream用法时,对集合的操作就很方便简单了。

什么是Stream?

点这里
Stream 是用函数式编程方式在集合类上进行复杂操作的工具,其集成了Java 8中的众多新特性之一的聚合操作,开发者可以更容易地使用Lambda表达式,并且更方便地实现对集合的查找、遍历、过滤以及常见计算等。

集合讲的是数据,流讲的是计算

1> Stream 自己不会存储元素
2> Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream
3> Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

Stream 的操作三个步骤
1> 创建 Stream : 一个数据源 (如 : 集合、数组), 获取一个流
2> 中间操作 : 一个中间操作链,对数据源的数据进行处理
3> 终止操作(终端操作) : 一个终止操作,执行中间操作链,并产生结果

创建流:
  1. collection中扩展了default 方法
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
collection.stream()
collection.parallelStream()
  1. Arrays 类中增加了 stream() 静态方法
    public static <T> Stream<T> stream(T[] array) {
        return stream(array, 0, array.length);
    }
	Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5, 6);
	int [] a = {1,2,3};
	IntStream aStream= Arrays.stream(a);

还有几种创建方法我没有掌握,读者可以点击上面的连接查看。

Stream的操作
操作类型接口方法
中间操作concat() distinct() filter() flatMap() limit() map() peek()skip() sorted() parallel() sequential() unordered()
结束操作allMatch() anyMatch() collect() count() findAny() findFirst() forEach() forEachOrdered() max() min() noneMatch() reduce() toArray()
  • 1 中间操作
方 法描 述
切片
filter(Predicate p)接收 Lambda , 从流中排除某些元素
distinct()筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
limit(long maxSize)保留前n个
skip(long n)去掉前n个
映射
map(Function f)接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
mapToDouble(ToDoubleFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream
mapToInt(ToIntFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream
mapToLong(ToLongFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream
flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
排序
sorted()产生一个新流,其中按自然顺序排序
sorted(Comparator comp)产生一个新流,其中按比较器顺序排序

我们来写一些例子加深印象,由于是中间方法所以在结尾加了foreach(终止方法)

//原数据
List<String> arrayList =Arrays.asList("1","2","3","3","4","5");
List<String> arrayList2 = Arrays.asList("a", "b", "c", "d", "e", "f");
  • 切片型

过滤filter

arrayList.stream().filter(e->e.equals("3")).forEach(System.out::println);
//3 3

删除重复distinct

arrayList.stream().distinct().forEach(System.out::println);
//1 2 3 4 5

筛选limit

arrayList.stream().limit(3).forEach(System.out::println);
//1 2 3

跳过skip

arrayList.stream().skip(4).forEach(System.out::println);
//4 5 
  • 映射型

map

arrayList.stream().map(e->e+"A").forEach(System.out::println);
//1A 2A 3A 3A 4A 5A

mapToInt/mapToDouble/mapToLong

arrayList.stream().mapToInt(e -> Integer.parseInt(e))
	.filter(e -> e==3).forEach(System.out::println);
//3 3

flatMap

Stream.of(arrayList, arrayList2).flatMap(u -> u.subList(0, 2).stream())
				.forEach(System.out::println);
//1 2 a b
  • 排序型

sorted

List<String> arrayList3 = Arrays.asList("9", "2", "3", "3", "4", "1");
arrayList3.stream().sorted().forEach(System.out::println);
// 1 2 3 3 4 9
arrayList3.stream().sorted((x, y) -> {
			return x.compareTo(y);
		}).forEach(System.out::println);
// 1 2 3 3 4 9

我好像对compareto,compareable,comparetor 是不是很懂,明天整理下

  • 2 终止操作
方 法描 述
allMatch(Predicate p)检查是否匹配所有元素
anyMatch(Predicate p)检查是否至少匹配一个元素
noneMatch(Predicate p)检查是否没有匹配所有元素
findFirst()返回第一个元素
findAny()返回当前流中的任意元素
count()返回流中元素总数
max(Comparator c)返回流中最大值
min(Comparator c)返回流中最小值
forEach(Consumer c)内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反, Stream API 使用内部迭代)
归纳
reduce(T iden, BinaryOperator b)可以将流中元素反复结合起来,得到一个值,返回 T
reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值,返回 Optional
收集
collect(Collector c)将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法

我们再来对终止操作进行举例:

reduce 将元素值结合起来

String sum =  arrayList.stream().reduce( "",(x,y)->(x+y) );
Optional<String> sum2 =  arrayList.stream().reduce((x,y)->(x+y) );
System.out.println( "Sum:  "+sum+"  Sum2:   "+ sum2 );
//Sum:  123345  Sum2:   Optional[123345]

anymatch/allmatch/nomatch

boolean flag = arrayList.stream().anyMatch(e->e.equals("1"));
System.err.println(flag);
// true

count

long num = arrayList.stream().count();
System.err.println("num: "+num+"  size: "+arrayList.size());

collection

		Map<String, List<String> > resultmap=arrayList.stream().collect(Collectors.groupingBy(e->{
			if ( e.equals("1") ) {
				return "ok";				
			}
			else {
				return e;
			}
			
		}));
						
		for (Entry entry : resultmap.entrySet()) {
			System.out.println(entry.getKey()+"   "+entry.getValue());
		}
		
//2   [2]
//3   [3, 3]
//4   [4]
//5   [5]
//ok   [1]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值