亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

JDK8新特性:使用stream、Comparator和Method Reference實現集合的優雅排序

2019-11-14 10:01:45
字體:
來源:轉載
供稿:網友

大家對java接口Comparator和Comparable都不陌生,JDK8里面Comparable還和以前一樣,沒有什么改動;但是Comparator在之前基礎上增加了很多static和default方法。本文主要結合JDK的stream編程,學習下Comparator。閱讀本文需要一些前置知識,可以參考如下文章。

JDK8新特性:接口的靜態方法和默認方法http://blog.csdn.net/aitangyong/article/details/54134385

JDK8新特性:函數式接口@FunctionalInterface的使用說明

http://blog.csdn.net/aitangyong/article/details/54137067

JDK8新特性:lambda入門http://blog.csdn.net/aitangyong/article/details/54317539JDK8新特性:使用Method References實現方法復用,簡化lambda表達式http://blog.csdn.net/aitangyong/article/details/54586197

可以使用Stream.sort對集合進行排序,sort有2個重載方法,區別如下。

// Student實現Comparable接口,默認按照id升序排列public class Student implements Comparable<Student>{	PRivate int id;	private int age;	private String name;	private Address address;	public Student(int id, int age, String name, Address address) {		this.id = id;		this.age = age;		this.name = name;		this.address = address;	}	public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public Address getAddress() {		return address;	}	public void setAddress(Address address) {		this.address = address;	}	@Override	public String toString() {		return "Student [id=" + id + ", age=" + age + ", name=" + name + ", address=" + address + "]";	}	@Override	public int compareTo(Student o) {		return this.id - o.id;	}}

stream().sorted()/Comparator.naturalOrder()/Comparator.reverSEOrder(),要求元素必須實現Comparable接口。
import java.util.ArrayList;import java.util.Comparator;import java.util.List;import java.util.stream.Collectors;public class TestComparator {	public static void main(String[] args) {		List<Student> students = buildStudents();				// 按照默認順序排序		List<Student> ascList1 = students.stream().sorted().collect(Collectors.toList());		System.out.println(ascList1);				// 按照自然序排序(其實就是默認順序)		List<Student> ascList2 = students.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());		System.out.println(ascList2);				// 按照默認順序的相反順序排序		List<Student> descList = students.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());		System.out.println(descList);	}	private static List<Student> buildStudents() {		List<Student> students = new ArrayList<>();		students.add(new Student(10, 20, "aty", new Address("d")));		students.add(new Student(1, 22, "qun", new Address("c")));		students.add(new Student(1, 26, "Zen", new Address("b")));		students.add(new Student(5, 23, "aty", new Address("a")));		return students;	}}如果Student沒有實現Comparable接口,效果如下:

接下來測試,都不要求Student實現Comparable接口,這里直接給出Student和Address實體類。

public class Student {	private int id;	private int age;	private String name;	private Address address;	public Student(int id, int age, String name, Address address) {		this.id = id;		this.age = age;		this.name = name;		this.address = address;	}	public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public Address getAddress() {		return address;	}	public void setAddress(Address address) {		this.address = address;	}	@Override	public String toString() {		return "Student [id=" + id + ", age=" + age + ", name=" + name + ", address=" + address + "]";	}}
public class Address {	private String address;	public Address(String address) {		super();		this.address = address;	}	public String getAddress() {		return address;	}	public void setAddress(String address) {		this.address = address;	}	@Override	public String toString() {		return "Address [address=" + address + "]";	}	}

Comparator.comparing(Function keyExtractor)生成1個Comparator對象,要求keyExtractor.apply()返回值一定要實現Comparable接口。比如下面代碼extractIdWay1和extractIdWay2都是等價的,從Student對象中提取id屬性,而id是int類型(Integer實現了Comparable)。
import java.util.ArrayList;import java.util.Comparator;import java.util.List;import java.util.function.Function;import java.util.stream.Collectors;public class TestComparator {	public static void main(String[] args) {		List<Student> students = buildStudents();		// 使用lambda表達式創建Function對象		Function<Student, Integer> extractIdWay1 = (student) -> student.getId();				// 使用方法引用簡化lambda		Function<Student, Integer> extractIdWay2 = Student::getId;				// Comparator.comparing(Function keyExtractor)		Comparator<Student> byId = Comparator.comparing(extractIdWay2);				// 升序		List<Student> ascList = students.stream().sorted(byId).collect(Collectors.toList());		System.out.println(ascList);				// 降序		List<Student> descList = students.stream().sorted(byId.reversed()).collect(Collectors.toList());		System.out.println(descList);	}	private static List<Student> buildStudents() {		List<Student> students = new ArrayList<>();		students.add(new Student(10, 20, "aty", new Address("d")));		students.add(new Student(1, 22, "qun", new Address("c")));		students.add(new Student(1, 26, "Zen", new Address("b")));		students.add(new Student(5, 23, "aty", new Address("a")));		return students;	}}

由于Student.getAddress()返回的對象沒有實現Comparable接口,所以不能通過Comparator.comparing()創建一個Comparator對象。

如果我們想安裝Address(沒有實現Comparable接口)排序怎么辦呢?使用另一種形式的comparing方法:

import java.util.ArrayList;import java.util.Comparator;import java.util.List;import java.util.stream.Collectors;public class TestComparator {	public static void main(String[] args) {		List<Student> students = buildStudents();		Comparator<Address> cmpAddr = Comparator.comparing(Address::getAddress);		Comparator<Student> byAddress = Comparator.comparing(Student::getAddress, cmpAddr);		List<Student> sortedAddressList = students.stream().sorted(byAddress).collect(Collectors.toList());		System.out.println(sortedAddressList);	}	private static List<Student> buildStudents() {		List<Student> students = new ArrayList<>();		students.add(new Student(10, 20, "aty", new Address("d")));		students.add(new Student(1, 22, "qun", new Address("c")));		students.add(new Student(1, 26, "Zen", new Address("b")));		students.add(new Student(5, 23, "aty", new Address("a")));		return students;	}}

這種形式的comparing()接收2個參數,第一個參數提取要排序的key,第二個參數指定排序的Comparator。自己指定比較器,可以靈活定制比較邏輯。比如,我們想實現字符串不區分大小寫比較。
//getName()返回String本身已經實現了Comparable,但是我們可以自己傳遞一個不區分大小寫的比較器Comparator<Student> byName = Comparator.comparing(Student::getName, String.CASE_INSENSITIVE_ORDER);List<Student> sortedNameList = students.stream().sorted(byName).collect(Collectors.toList());System.out.println(sortedNameList);comparingDouble()、comparingLong()、comparingInt()不過是comparing()更具體的版本,使用方式相同。
public static void main(String[] args) {	List<Student> students = buildStudents();	Comparator<Student> byAge1 = Comparator.comparingInt(Student::getAge);	Comparator<Student> byAge2 = Comparator.comparing(Student::getAge);	List<Student> sortedAgeList1 = students.stream().sorted(byAge1).collect(Collectors.toList());	List<Student> sortedAgeList2 = students.stream().sorted(byAge2).collect(Collectors.toList());	System.out.println(sortedAgeList1);	System.out.println(sortedAgeList2);}private static List<Student> buildStudents() {	List<Student> students = new ArrayList<>();	students.add(new Student(10, 20, "aty", new Address("d")));	students.add(new Student(1, 22, "qun", new Address("c")));	students.add(new Student(1, 26, "Zen", new Address("b")));	students.add(new Student(5, 23, "aty", new Address("a")));	return students;}Comparator.nullsFirst()和Comparator.nullsLast(),前面我們創建的Student列表中沒有null,如果有null的話,上面的代碼都會拋異常。而這2個方法就是用來處理null的,一個認為null比所有非null都小,一個認為比所有都大。
public class TestComparator {	public static void main(String[] args) {		List<Student> students = buildStudents();		Comparator<Student> nullNotAllowed = Comparator.comparing(Student::getId);		Comparator<Student> allowNullComparator = Comparator.nullsFirst(nullNotAllowed);				// 正常排序		List<Student> result1 = students.stream().sorted(allowNullComparator).collect(Collectors.toList());		System.out.println(result1);				// 拋異常		List<Student> result2 = students.stream().sorted(nullNotAllowed).collect(Collectors.toList());		System.out.println(result2);	}	private static List<Student> buildStudents() {		List<Student> students = new ArrayList<>();		students.add(new Student(10, 20, "aty", new Address("d")));		students.add(new Student(1, 22, "qun", new Address("c")));		students.add(new Student(1, 26, "Zen", new Address("b")));		students.add(new Student(5, 23, "aty", new Address("a")));		students.add(null);		return students;	}}至此Comparator的static方法已經介紹完畢,接下來我們看下它的default方法。

reversed()前面已經介紹了,返回一個新的比較器(排序順序相反)

thenComparing()系列方法與comparing()使用方法類似

如果我們先按照id排序,id相等的話再按照name排序,那么可以這樣寫。

public static void main(String[] args) {	List<Student> students = buildStudents();		// id升序	Comparator<Student> byIdASC = Comparator.comparing(Student::getId);		// named不分區大小寫降序	Comparator<Student> byNameDESC = Comparator.comparing(Student::getName, String.CASE_INSENSITIVE_ORDER)			.reversed();	// 聯合排序	Comparator<Student> finalComparator = byIdASC.thenComparing(byNameDESC);		List<Student> result = students.stream().sorted(finalComparator).collect(Collectors.toList());	System.out.println(result);}private static List<Student> buildStudents() {	List<Student> students = new ArrayList<>();	students.add(new Student(10, 20, "aty", new Address("d")));	students.add(new Student(1, 22, "qun", new Address("c")));	students.add(new Student(1, 26, "Zen", new Address("b")));	students.add(new Student(5, 23, "aty", new Address("a")));	return students;}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品成人久久av| 亚洲一区二区免费| 日韩动漫免费观看电视剧高清| 91久久精品国产91久久性色| 欧美在线一区二区视频| 中文字幕在线国产精品| 日韩在线免费视频| 久久久www成人免费精品张筱雨| 亚洲国产91精品在线观看| 色综合久久88色综合天天看泰| 欧美日韩在线免费| 精品视频在线播放免| 亚洲最新在线视频| 成人激情视频在线| 国产日韩欧美91| 日本久久久久久久久| 亚洲精品视频在线观看视频| 国产欧美一区二区三区四区| 日韩欧美国产一区二区| 午夜精品久久久久久久久久久久| 亚洲欧美日韩国产中文| 日韩在线资源网| 欧美激情在线有限公司| 最新69国产成人精品视频免费| 国自产精品手机在线观看视频| 在线观看91久久久久久| 国产不卡精品视男人的天堂| 欧美电影《睫毛膏》| 尤物99国产成人精品视频| 久久久av亚洲男天堂| 亚洲高清不卡av| 欧美一级大片在线观看| 亚洲免费视频观看| 日韩欧美中文字幕在线观看| 日韩视频免费观看| 韩国视频理论视频久久| 97在线观看视频国产| 国产精品久久久久av免费| 欧美床上激情在线观看| 国产精品久久国产精品99gif| 国产精品久久久久一区二区| 91嫩草在线视频| 欧美一区二区三区艳史| 国产区精品在线观看| 亚洲乱亚洲乱妇无码| 综合欧美国产视频二区| 国产精品看片资源| 国产精品一区二区三| 毛片精品免费在线观看| 精品久久久久久久久国产字幕| 国内精品久久影院| 欧美成人免费网| 亚洲一区二区三区毛片| 日本伊人精品一区二区三区介绍| 久久国产精彩视频| 久久精品这里热有精品| 国产精品国内视频| 久久成人免费视频| 日韩人体视频一二区| 中文字幕免费国产精品| 国产日韩欧美视频在线| 日韩精品欧美国产精品忘忧草| 欧美成人在线影院| 视频一区视频二区国产精品| 欧美激情国产高清| 欧美成人午夜激情视频| 久久久久久久影视| 精品激情国产视频| 欧美成人精品h版在线观看| 欧美日韩精品中文字幕| 久久久免费电影| 日韩在线免费视频| 在线观看欧美成人| 欧美成aaa人片免费看| 欧美黄色成人网| 国产精品av在线播放| 97色在线视频观看| 国产精品va在线| 亚洲精品456在线播放狼人| 精品香蕉在线观看视频一| 91精品国产自产91精品| 国产精品美腿一区在线看| 最近2019中文字幕第三页视频| 国产精品丝袜一区二区三区| 久久久久久久久国产| 日韩欧美国产中文字幕| 91久久夜色精品国产网站| 精品高清美女精品国产区| 色噜噜亚洲精品中文字幕| 动漫精品一区二区| 国产成人高潮免费观看精品| 欧美做受高潮电影o| 国产香蕉97碰碰久久人人| 亚洲国产欧美一区二区三区同亚洲| 日韩中文字在线| 久久精品色欧美aⅴ一区二区| 亚洲精品日韩av| 国产精品免费在线免费| 日韩美女在线看| 国产精品白嫩美女在线观看| 国产精品九九九| 欧美国产亚洲视频| 亚洲欧美日韩精品久久奇米色影视| 日韩免费av在线| 一本一本久久a久久精品牛牛影视| 亚洲成人黄色网| 亚洲人成毛片在线播放| 九九热99久久久国产盗摄| 97婷婷大伊香蕉精品视频| 日韩电影在线观看永久视频免费网站| 日韩中文在线中文网在线观看| 国产精品一区二区三区毛片淫片| 欧美色视频日本版| 国产精品黄视频| 色悠悠国产精品| 欧美成人精品一区二区三区| 国产免费久久av| 国产成人av在线播放| 亚洲人成伊人成综合网久久久| 亚洲石原莉奈一区二区在线观看| 国产精品久久国产精品99gif| 亚洲最新av在线网站| 国内精品久久久久伊人av| 欧美成人激情视频免费观看| 色多多国产成人永久免费网站| 日韩av电影免费观看高清| 中文字幕亚洲国产| 日韩av免费在线观看| 欧美专区国产专区| 久久网福利资源网站| 欧美天天综合色影久久精品| 欧美国产亚洲精品久久久8v| 亚洲第一精品夜夜躁人人躁| 久久精品欧美视频| 久久99久久99精品中文字幕| 777精品视频| 国产成人精品免高潮费视频| 欧美日韩国产999| 日韩精品在线看| 欧美日韩一区二区免费视频| 丝袜美腿精品国产二区| 亚洲欧美在线免费| 亚洲女人被黑人巨大进入al| 久久免费视频这里只有精品| 国产精品久久久久一区二区| 国产精品∨欧美精品v日韩精品| 91精品国产777在线观看| 国产精品女人久久久久久| 日本一区二三区好的精华液| 日韩精品免费在线观看| 久久久免费高清电视剧观看| 欧美激情乱人伦一区| 人人澡人人澡人人看欧美| 亚洲欧美日韩综合| 第一福利永久视频精品| 日韩视频免费观看| 欧美巨乳美女视频| 97人洗澡人人免费公开视频碰碰碰| 久久91超碰青草是什么| 中文字幕亚洲在线| 久久精品亚洲一区| 国产91|九色| 正在播放欧美视频| 成人欧美一区二区三区在线湿哒哒|