Java8新特性Stream之映射

一个非常常见的数据处理套路就是从某些对象中选择信息。比如在SQL里,你可以从表中选
择一列。Stream API也通过map和flatMap方法提供了类似的工具。

映射

1.map

流支持map方法,它会接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映 射成一个新的元素(使用映射一词,是因为它和转换类似,但其中的细微差别在于它是“创建一 个新版本”而不是去“修改”)。
例如下面的例子,通过方法引用的方式获取学生名字:

class Test{
	public static void main(String []args) {
		 List<Student> stuList = Arrays.asList(new Student("xiaoming",18),
				 							   new Student("xiaoli",22),
				 							   new Student("xiaozhang",19),
				 							   new Student("Tom",26),
				 							   new Student("Kevin",20),
				 							   new Student("Lucy",26)
				 							   );
		 
		 Stream<String> nameStream = stuList.stream().map(Student::getName);
		 nameStream.forEach(System.out::println);
	}
}

Output:

xiaoming
xiaoli
xiaozhang
Tom
Kevin
Lucy

因为getName方法返回一个String,所以map方法输出的流的类型就是Stream< String >.

再比如,获取到名字后还想获取每一个名字的长度:

 Stream<Integer> nameStream = stuList.stream().map(Student::getName).map(String::length);
 nameStream.forEach(System.out::println);

2.流的扁平化

如果我们写一个方法,用于接收字符串,并返回一个流

public static Stream<Character> filterCharacter(String str){ //接受String类型,返回一个流Stream
		List<Character> list = new ArrayList<>();
		
		for(Character ch : str.toCharArray()) { //将String类型的str变成character类型并用ch接收
			list.add(ch);
		}
			
		return list.stream(); //返回一个list流
				
	}

我们想获取List中的每个字母:

class Test{
	public static void main(String []args) {
		 List<String> list =Arrays.asList("aa","bb","cc","dd");
		 
		 //map()出来的就是流Stream<>,Test::filterCharacter方法出来的还是流Stream
		 Stream<Stream<Character>> stream1=list.stream().map(Test::filterCharacter);
		 
		 //stream1的类型是Stream>,第一个forEach循环是外层Stream<>
		 stream1.forEach(sm ->{
			 sm.forEach(System.out::println);
		 });
		 
	}

Output:

a
a
b
b
c
c
d
d

通过这样的方式获取List中的每个字母有些麻烦,实际上是把两个流合在一起然后分别遍历出来的结果。但是通过flatmap的方法会简单很多:

Stream<Character> sm =list.stream().flatMap(Test::filterCharacter);
sm.forEach(System.out::println);

简而言之,flatmap方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流。

例题:
给定两个数字列表,如何返回所有的数对呢?例如,给定列表[1, 2, 3]和列表[3, 4],应 该返回[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]。为简单起见,你可以用有两个元素的数组来代 表数对。

List<Integer> numbers1 = Arrays.asList(1, 2, 3); List<Integer> numbers2 = Arrays.asList(3, 4); List<int[]> pairs =
         numbers1.stream()
                 .flatMap(i -> numbers2.stream()
                                       .map(j -> new int[]{i, j})
)
                 .collect(toList());

你可能感兴趣的:(Java函数式编程)