stream流

stream流比传统的集合遍历方式代码更加简化
以下为传统方式:

package stream;

import java.util.ArrayList;
import java.util.List;
/*
 以下对集合中的元素进行了三次遍历
 一共三个循环,每个循环的作用不一样。
 我们对集合的元素进行操作的时候,总是需要进行循环。
但是循环不是我们的目的,我们的目的是输出结果

 */
public class TraditionalList {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建一个List集合,存储姓名
		List<String> list = new ArrayList<>();
		list.add("张莹莹");
		list.add("周莹莹");
		list.add("张莹");
		list.add("陈莹");
		list.add("张问问");

		//对list集合中的元素进行过滤,只要以张开头的元素存储到一个新的集合中
		List<String> list1 = new ArrayList<>();
		for(String s : list) {
			if(s.startsWith("张")) {
				list1.add(s);
			}
		}
		
		//对list1集合进行过滤,只要姓名长度为3的人,存储到一个新集合中
		List<String> list2 = new ArrayList<>();
		for(String s : list1) {
			if(s.length()==3) {
				list2.add(s);
			}
		}
		//遍历筛选完后的list2集合并打印
		for(String s:list2) {
			System.out.println(s);
		}
	}

}

使用stream流后(注意.filter后面若连续条件则不加分号):

package stream;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class StreamDemo1 {
/*
 *  * Stream可以简化我们的过程,stream流是JDK1.8之后出现的,
 * 关注的是做什么,而不是怎么做。
 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建一个List集合,存储姓名
		List<String> list = new ArrayList<>();
		list.add("张莹莹");
		list.add("周莹莹");
		list.add("张莹");
		list.add("陈莹");
		list.add("张问问");
		list.stream()
		.filter(new Predicate<String>() {

			@Override
			public boolean test(String name) {
				// TODO Auto-generated method stub
				return name.startsWith("张");
			}
			
		})
		.filter(new Predicate<String>() {

			@Override
			public boolean test(String name) {
				// TODO Auto-generated method stub
				return name.length()==3;
			}
			
		})
		.forEach(new Consumer<String>() {

			@Override
			public void accept(String name) {
				// TODO Auto-generated method stub
				System.out.println(name);
			}
			
		});
	}

}

使用Lambda表达式后:

package stream;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class StreamDemo1 {
/*
 *  * Stream可以简化我们的过程,stream流是JDK1.8之后出现的,
 * 关注的是做什么,而不是怎么做。
 */
	public static void main(String[] args) {
		//创建一个List集合,存储姓名
		List<String> list = new ArrayList<>();
		list.add("张莹莹");
		list.add("周莹莹");
		list.add("张莹");
		list.add("陈莹");
		list.add("张问问");

		list.stream()
		.filter(name->name.startsWith("张"))
		.filter(name->name.length()==3)
		.forEach(name->System.out.println(name));
	}

}

输出结果:
张莹莹
张问问

Filter()可以实现按条件对集合进行过滤。
注意stream流的创建方法。

以下场景:你是公司某个岗位的HR,收到了大量的简历,为了节约时间,现需按照一点规则过滤一下这些简历。比如要经常熬夜加班,所以只招收男性。

package stream;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;



//求职者的实体类
public class Person {
	private String name;//姓名
	private Integer age;//年龄
	private String gender;//性别
	//构造方法
	public Person(String name,Integer age,String gender) {
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	//其他getter、setter方法略
	public void setGender(String gender) {
		this.gender = gender;
	}
	public String getGender() {
		return gender;
	}
	//重写toString(),方便观看结果
	public String toString() {
		return "Person{" +
				"name=" + name + '\'' +
				",age = " + age +
				",gender = " + gender +'\'' +
				"}";
	}
	
	public static void main(String[] args) {
		Collection<Person> collection = new ArrayList<>();
		collection.add(new Person("张莹莹",22,"女"));
		collection.add(new Person("张王五",22,"男"));
		collection.add(new Person("陈练",22,"男"));
		collection.add(new Person("张莹",22,"女"));
		collection.add(new Person("张偶",22,"女"));
		
		Stream<Person> personStream = collection.stream().filter(new Predicate<Person>() {

			@Override
			public boolean test(Person person) {
				return "男".contentEquals(person.getGender());//只保留男性
			}
			
		});
		collection = personStream.collect(Collectors.toList());//将Stream转化为list
		System.out.println(collection.toString());
	}
}

collect(toList()),在流中生成列表。
collect也就是收集器,是Stream一种通用的、从流生成复杂值的结构。只要将它传给collect方法,也就是所谓的转换方法,其就会生成想要的数据结构。

使用Lambda简化代码后:

		/*Stream<Person> personStream = collection.stream().filter(new Predicate<Person>() {

			@Override
			public boolean test(Person person) {
				// TODO Auto-generated method stub
				return "男".contentEquals(person.getGender());
			}
			
		});
		collection = personStream.collect(Collectors.toList());
		*/
		//使用Lambda表达式简化代码
		Stream<Person> personStream = collection.stream().filter(person->"男".equals(person.getGender()));
		collection = personStream.collect(Collectors.toList());
		System.out.println(collection.toString());

Stream流的常用创建方法:


		List<String> list = new ArrayList<>();
		Stream<String> stream = list.stream();

将数组转成Stream流

		Integer[] nums = new Integer[10];
		Stream<Integer> stream = Arrays.stream(nums);

使用Stream中的静态方法:of()

		String[] arr = {"ddd","ddddffff"};
		Stream<String> stream2 = Stream.of(arr);

也可以使用Arrays里的stream方法,将数组转换为流:

		String[] arr = {"ddd","ddddffff"};
		Stream<String> stream3 = Arrays.stream(arr);
		//或者:
		Integer[] nums = new Integer[2];
		Stream<Integer> stream4 = Arrays.stream(nums);

forEach是一个终结方法,遍历之后就不能继续调用stream流中的其他方法。

		
		Stream<String> stream = Stream.of("张单","李单","王单","辰单");
	//使用Stream流中的方法forEach对数据进行遍历
	/*	stream.forEach((String name)->{
			System.out.println(name);
		});*/
		//Lambda表达式简化代码:
		stream.forEach(name->System.out.println(name));
	}

stream流属于管道流,只能被消费(使用)一次,
第一个stream流调用完毕方法,数据就会流转到下一个stream上
所以第一个stream流就不能再调用方法了。

stream中的map方法可以将当前流中的T类型数据转换为R类型数据。
例如:需要将字符串类型的整数转换(映射)为Integer类型的整数

package stream;

import java.util.stream.Stream;

public class StreamMap {

	public static void main(String[] args) {
	
		Stream<String> stream = Stream.of("1","2","3");
		//使用map方法,把字符串类型的整数转换(映射)为Integer类型的整数
		Stream<Integer> stream2 = stream.map((String s)->Integer.parseInt(s)
		);
		//遍历
		stream2.forEach(i->System.out.println(i));
	}

}

stream中的count用于统计stream流中元素个数 ,是一个终结方法,不能在使用这个方法后再调用stream流中的其他方法。

package stream;

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

public class streamCount {

	public static void main(String[] args) {
		Collection<Integer> list = new ArrayList<>();
		list.add(1);
		list.add(2);
		list.add(3);
		Stream<Integer> s = list.stream();
		long count =s.count();
		System.out.println(count);
	}
}

### Stream的工作原理及实现机制 Stream是一种用于处理集合数据的强大工具,其核心思想是提供一种声明式的编程方式来对数据进行过滤、映射和聚合等操作。以下是关于Stream工作原理及其实现机制的具体说明: #### 1. **Stream的核心概念** Stream并不是一种新的数据结构,而是一个抽象层,它允许开发者以函数式风格对数据源(如`List`、`Set`或数组)中的元素执行各种高级操作[^1]。 - 数据源:Stream可以从任何支持迭代的对象中获取数据,比如`Collection`接口的子类、数组或其他自定义数据源。 - 中间操作:这些操作不会直接修改原始数据源,而是返回一个新的Stream实例供后续操作使用。例如`filter()`、`map()`等方法属于中间操作。 - 终端操作:当调用终端操作时,Stream才会真正开始执行所有的中间操作链,并最终生成结果。典型的终端操作有`forEach()`、`collect()`、`reduce()`等。 #### 2. **延迟执行机制** Stream的一个重要特性就是它的懒加载(Lazy Evaluation)。这意味着只有在触发终端操作的时候,Stream才会依次执行之前注册的一系列中间操作[^3]。这种设计不仅提高了性能,还减少了不必要的计算开销。例如,在一个大数据集中查找符合条件的第一个元素时,一旦找到目标就可以停止进一步的操作,而不是遍历整个数据集。 #### 3. **内部工作机制** - 当创建了一个Stream之后,实际上只是建立了一条针对特定数据源的操作管道。 - 接下来每增加一个中间操作,都会在这个管道上附加一层额外的功能描述,但并不会立刻去改变底层的数据状态。 - 只有到达最后一步——即某个具体的收集动作被发起后,整套程才正式运行起来,按照预定顺序逐项完成各项任务直至得出最终成果。 #### 4. **并行处理能力** 得益于Java内置的支持以及现代硬件架构的优势,Streams API还能轻松切换至并行模式来进行大规模并发运算。这主要依赖于Fork/Join框架配合Spliterator共同协作达成目的。通过这种方式可以在多核处理器环境下显著提升整体吞吐量水平[^3]。 ```java // 并行示例 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.parallelStream() .filter(n -> n % 2 == 0) .mapToInt(Integer::intValue) .sum(); ``` 以上代码片段展示了如何利用并行快速求解列表里偶数总和的过程。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值