JDK1.8中的Lambda公式--03【收集器Collectors的API】

1.方法引用

Lambda 表达式有一个常见的用法: Lambda 表达式经常调用参数。 比如想得到艺术家的姓名, Lambda 的表达式如下:
artist -> artist.getName()
这种用法如此普遍, 因此 Java 8 为其提供了一个简写语法, 叫作方法引用, 帮助程序员重用已有方法。 用方法引用重写上面的 Lambda 表达式, 代码如下:
Artist::getName
标准语法为 Classname::methodName。 

2.使用收集器

package com.mmmm.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.mmmm.model.Album;
import com.mmmm.model.Artist;
import com.mmmm.model.Track;

public class Test_03 {

	public static void main(String[] args) {

		List<String> list_01=Stream.of("1", "2", "3")
				.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
		System.out.println(list_01);

		String list_02=Stream.of("1", "2", "3")
				.collect(Collectors.collectingAndThen(Collectors.toList(), list->list.toString()));
		System.out.println(list_02);

		List<String> list_03=Stream.of("1", "2", "3")
				.collect(Collectors.toList());
		System.out.println(list_03);

		Set<String> list_04=Stream.of("1", "2", "3")
				.collect(Collectors.toSet());
		System.out.println(list_04);

		TreeSet<String> list_05=Stream.of("5", "2", "3")
				.collect(Collectors.toCollection(TreeSet::new));
		System.out.println(list_05);

		//1.找出成员最多的乐队
		List<Artist> musicians=new ArrayList<Artist>();
		musicians.add(new Artist("JiaKeChong",Arrays.asList("zhangsan","lisi","wangwu") , "Americ"));
		musicians.add(new Artist("TFBOYS",Arrays.asList("wangyuan","wang","yiyangqianxi") , "China"));
		musicians.add(new Artist("xiha",Arrays.asList("lili") , "Italy"));
		musicians.add(new Artist("yangmi",Arrays.asList("lilian") , "Italy"));
		System.out.println("成员最多的乐队:方法一"+biggestGroup_01(musicians.stream()).get());
		System.out.println("成员最多的乐队:方法二"+biggestGroup_02(musicians.stream()).get());
		//2.找出一组专辑上曲目的平均数
		List<Album> albumList = new ArrayList<>();
		List<Track> trackList_1 = new ArrayList<>();
		trackList_1.add(new Track("song_01"));

		List<Track> trackList_2 = new ArrayList<>();
		trackList_2.addAll(trackList_1);
		trackList_2.add(new Track("song_02"));
		trackList_2.add(new Track("song_03"));


		List<Track> trackList_3 = new ArrayList<>();
		trackList_3.addAll(trackList_2);
		trackList_3.add(new Track("song_04"));
		trackList_3.add(new Track("song_05"));
		trackList_3.add(new Track("song_06"));
		trackList_3.add(new Track("song_07"));

		albumList.add(new Album("xingxing", trackList_1, musicians));
		albumList.add(new Album("xingxing", trackList_2, musicians));
		albumList.add(new Album("xingxing", trackList_3, musicians));

		System.out.println("专辑上曲目的平均数:"+averageNumberOfTracks(albumList));
		System.out.println("专辑上曲目的总数:"+sumNumberOfTracks(albumList));
		//3.数据分块
		System.out.println("艺术家里面是solo的是:"+getArtistIsSoloOrNot(musicians).get(true));
		System.out.println("艺术家里面不是solo的是:"+getArtistIsSoloOrNot(musicians).get(false));
		//4.字符串
		System.out.println("艺术家的姓名:"+getName(musicians));
		
		StringJoiner combined =
				musicians.stream()
				.map(Artist::getName)
				.reduce(new StringJoiner(", ", "[", "]"),
						StringJoiner::add,
						StringJoiner::merge);
				String result = combined.toString();
		System.out.println(result);
	}
	/**
	 * 找出成员最多的乐队方法1
	 * @param artists
	 * @return
	 */
	public static Optional<Artist> biggestGroup_01(Stream<Artist> artists) {
		Function<Artist,Long> getCount = artist ->artist.getMembers()==null?0:artist.getMembers().stream().count();
		return artists.collect(Collectors.maxBy(Comparator.comparing(getCount)));
	}
	/**
	 * 找出成员最多的乐队方法2
	 * @param artists
	 * @return
	 */
	public static Optional<Artist> biggestGroup_02(Stream<Artist> artists) {
		return artists.collect(Collectors.maxBy(Comparator.comparing(artist ->artist.getMembers()==null?0:artist.getMembers().stream().count())));
	}

	/**
	 * 找出一组专辑上曲目的平均数
	 * @param albums
	 * @return
	 */
	public static double averageNumberOfTracks(List<Album> albums) {
		return albums.stream()
				.collect(Collectors.averagingInt(album -> album.getTracks().size()));
	}
	/**
	 * 找出一组专辑上曲目的总数
	 * @param albums
	 * @return
	 */
	public static double sumNumberOfTracks(List<Album> albums) {
		return albums.stream()
				.collect(Collectors.summingDouble(album -> album.getTracks().size()));
	}
	
	/**
	 * 数据分块
	 * 艺术家中是solo的和不是solo的分块
	 * 
	 */
	public static Map<Boolean, List<Artist>> getArtistIsSoloOrNot(List<Artist> artists){
		
		return artists.stream().collect(Collectors.partitioningBy(artist->artist.getMembers().size()==1));
		
	}
	
	/**
	  * 编写一个函数,接受艺术家列表作为参数,返回一个字符串列表,其中包含艺术家的姓名;
	  * 
	  * @param musicians
	  * @return
	  */
	 public static String getName(List<Artist> musicians) {

		 String nameAndOrigin = musicians.stream()
			//  .map(artist -> "name:" + artist.getName() + ",origin:" + artist.getOrigin() + ";")
	    .map(Artist::getName)
	    .collect(Collectors
	    		.joining(",name:", "[name:", "]"));
	  return nameAndOrigin;

	 }
	 
	/**
	 * 组合收集器
	 *  使用收集器求每个艺术家的专辑名
	 * @param albums
	 * @return
	 */
	 public Map<Artist, List<String>> nameOfAlbums(Stream<Album> albums) {
		 return albums.collect(Collectors.groupingBy(Album::getMainMusician,
				 Collectors.mapping(Album::getName, Collectors.toList())));
		 }
	 
	 /**
	  * 组合收集器
	  * 使用收集器计算每个艺术家的专辑数
	  * @param albums
	  * @return
	  */
	 public Map<Artist, Long> numberOfAlbums(Stream<Album> albums) {
		 return albums.collect(Collectors.groupingBy(album -> album.getMainMusician(),
		 Collectors.counting()));
		 }
}

3.练习题

/*1. 方法引用
回顾第 3 章中的例子, 使用方法引用改写以下方法:
a. 转换大写的 map 方法;
b. 使用 reduce 实现 count 方法;
c. 使用 flatMap 连接列表。*/

//a. 转换大写的 map 方法;
		System.out.println(Stream.of("a","b","c").map(String::toUpperCase).collect(Collectors.toList()));
		System.out.println(Stream.of("a","b","c").map(str->str.toUpperCase()).collect(Collectors.toList()));
		//b. 使用 reduce 实现 count 方法;
		System.out.println(Stream.of(1,2,3).reduce(0,(acc,element)->acc+element));
		//c. 使用 flatMap 连接列表
		List<Integer> together = Stream.of(Arrays.asList(1, 2), Arrays.asList(3, 4))
					.flatMap(Collection::stream)
					.collect(Collectors.toList());
		System.out.println(together);

2. 收集器
a. 找出名字最长的艺术家, 分别使用收集器和第 3 章介绍过的 reduce 高阶函数实现。68 | 第 5 章
然后对比二者的异同: 哪一种方式写起来更简单, 哪一种方式读起来更简单? 以下面
的参数为例, 该方法的正确返回值为 "Stuart Sutcliffe":
Stream<String> names = Stream.of("John Lennon", "Paul McCartney",

"George Harrison", "Ringo Starr", "Pete Best", "Stuart Sutcliffe");

	//1.找出名字最长的艺术家
		Stream<String> names = Stream.of("John Lennon", "Paul McCartney",
				"George Harrison", "Ringo Starr", "Pete Best", "Stuart Sutcliffe");
		System.out.println("名字最长的艺术家:"+names.collect(Collectors.maxBy(Comparator.comparing(name->name.length()))).get());
		


b. 假设一个元素为单词的流, 计算每个单词出现的次数。 假设输入如下, 则返回值为一
个形如 [John → 3, Paul → 2, George → 1] 的 Map:
Stream<String> names = Stream.of("John", "Paul", "George", "John",

 

"Paul", "John");

 

//2.假设一个元素为单词的流, 计算每个单词出现的次数。 假设输入如下, 则返回值为一个形如 [John → 3, Paul → 2, George → 1] 的 Map
		Stream<String> names2 = Stream.of("John", "Paul", "George", "John",
				"Paul", "John");
		
		Map<String,Long> map=names2.collect(Collectors.groupingBy(name->name,Collectors.counting()));
		System.out.println(map);
		Stream<String> names3 = Stream.of("John", "Paul", "George", "John",
				"Paul", "John");
		Map<Object, List<String>> map2=names3.collect(Collectors.groupingBy(name->name));
		System.out.println(map2);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值