参考链接:
-
java list 根据string排序Java对List集合,String数组排序weixin_39610594的博客-CSDN博客
-
Collections.sort(List list)与Collections.sort(List list,Comparator c)用法_Coder_Cui的博客-CSDN博客
1. 前期准备
1.1 People类(name、age,未实现Comparable接口)
package sort; /** * @ClassName People * @Description TODO * @Author Jiangnan Cui * @Date 2022/11/13 15:08 * @Version 1.0 */ public class People { private String name; private Integer age; public People(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "People{" + name + "-" + age + '}'; } }
1.2 User类(name、age,已实现Comparable接口)
package sort; /** * @ClassName User * @Description TODO * @Author Jiangnan Cui * @Date 2022/11/13 10:54 * @Version 1.0 */ public class User implements Comparable<User>{ private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + name + "-" + age + '}'; } @Override public int compareTo(User user) { /** * 1.定义单条件排序规则 */ // return this.age - user.getAge();// 按照年龄升序排列 // return Integer.compare(this.age,user.getAge());// 作用同上 // return this.age < user.getAge() ? -1 : 1;// 作用同上 // return this.age >= user.getAge() ? 1 : -1;// 作用同上 // return user.age - this.getAge();// 按照年龄降序排列 // return Integer.compare(user.getAge(), this.age);// 作用同上 // return user.age < this.getAge() ? -1 : 1;// 作用同上 // return user.age >= this.getAge() ? 1 : -1;// 作用同上 // return this.name.length() - user.getName().length();// 按照姓名长度升序排列 // return Integer.compare(this.name.length(),user.getName().length());// 作用同上 // return this.name.length() < user.getName().length() ? -1 : 1;// 作用同上 // return this.name.length() >= user.getName().length() ? 1 : -1;// 作用同上 // return user.getName().length() - this.name.length();// 按照姓名长度降序排列 // return Integer.compare(user.getName().length(),this.name.length());// 作用同上 // return user.getName().length() < this.name.length() ? -1 : 1;// 作用同上 // return user.getName().length() >= this.name.length() ? 1 : -1;// 作用同上 /** * 2.定义多条件比较规则:先按照年龄升序排列,再按照姓名长度升序排列 */ if(this.age > user.getAge()){ return 1; }else if(this.age < user.getAge()){ return -1; }else{ return this.name.length() - user.getName().length(); } } }
1.3 总结
-
实体类(除基本类型、String类型,它们的底层已实现Comparable接口,可直接调用sort方法进行排序,举例:Integer类型可直接升序排列、String类型可直接按照字符顺序排序)在实现Comparable接口后,必须要重写compareTo方法:
-
Comparable接口不指定泛型时,重写方法为:
public class User implements Comparable{ @Override public int compareTo(Object o) { // 此时需要强制类型转换 if(o instanceof User){ User user = (User)o; // 然后才可通过get方法获取User属性 } } }
-
Comparable接口指定泛型(如:User)时,重写方法为:
public class User implements Comparable<User>{ @Override public int compareTo(User user) { // 此时可直接通过get方法获取User属性 } }
-
-
Comparable是自然排序的接口,实现此接口的类,就拥有了比较大小的能力,此接口中只有一个public int compareTo方法,在方法体中既可定义单条件比较规则,也可定义多条件比较规则,其返回值定义如下:
-
返回值>0,正数,代表当前对象this比传入对象大,升序,从小到大排序
-
返回值=0,零,代表当前对象this等于传入对象
-
返回值<0,负数,代表当前对象this比传入对象小,降序,从大到小排序
举例:Integer中的compareTo方法
/** * Compares two {@code Integer} objects numerically. * * @param anotherInteger the {@code Integer} to be compared. * @return the value {@code 0} if this {@code Integer} is * equal to the argument {@code Integer}; a value less than * {@code 0} if this {@code Integer} is numerically less * than the argument {@code Integer}; and a value greater * than {@code 0} if this {@code Integer} is numerically * greater than the argument {@code Integer} (signed * comparison). * @since 1.2 */ public int compareTo(Integer anotherInteger) { return compare(this.value, anotherInteger.value); } /** * Compares two {@code int} values numerically. * The value returned is identical to what would be returned by: * <pre> * Integer.valueOf(x).compareTo(Integer.valueOf(y)) * </pre> * * @param x the first {@code int} to compare * @param y the second {@code int} to compare * @return the value {@code 0} if {@code x == y}; * a value less than {@code 0} if {@code x < y}; and * a value greater than {@code 0} if {@code x > y} * @since 1.7 */ public static int compare(int x, int y) { return (x < y) ? -1 : ((x == y) ? 0 : 1); }
-
x<y:-1
-
x=y:0
-
x>y:1
-
-
参考链接:compareTo返回值为-1 、 1 、 0代表的意义总结Mickey_flY的博客-CSDN博客compareto方法返回值
int compareTo(T o):比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
升序(默认,即官方定义,毕竟代码实现就是基于这个写的):
< -1 = 0 //或者 1效果是一样的;-1相同元素会发生位置调整 1
降序:
< 1 = 0 //或者 1效果是一样的;-1相同元素会发生顺序调整 -1
倒序:
// 直接 return -1;
不改变顺序:
// 直接 return 0或者1;
很多人总结了权重的问题:
-
1是前者权重大,-1是后者。JAVA则按照权重由小到大排序。这样说法也好理解: 如果当前值<传递过来的值,返回-1,则后者权重大,升序排列 如果想要降序,则需要当前值<传递过来的值返回1,则前者权重大 这样写代码的时候,你只要考虑权重就能得到满足需求
-
但还有更加精辟的解释:如果返回负数,第一个参数放前面;按照官方默认来看: 当前值<传递过来的值,返回-1,则返回小的那个数放在前边,这样就是升序排列 同样当当前值>传递过来的值是返回-1的话,大的那个数就在前边,这样就是降序排列了 这样我们不管降序升序只要保证返回是-1的那个条件符合你的需求就行了。
参考链接:compareTo返回值为-1 、 1 、 0 的排序问题 - 人情世故 - 博客园 (cnblogs.com)
/** * 升序排列 */ @Override public int compareTo(Note<T> o){ if(this.weight>o.weight){ return 1; }else if(this.weight<o.weight){ return -1; } return 0; } /** * 倒序排列 */ @Override public int compareTo(Note<T> o) { if(o.weight>this.weight){ return 1; }else if(o.weight<this.weight){ return -1; } return 0; }
(快速记忆法)当前对象与后一个对象进行比较,如果比较结果为1进行交换,其他不进行交换。
-
当后一个对象比当前对象大,返回结果值为1时,前后交换,说明是倒序排列。
-
当后一个对象比当前对象小,返回结果值为1时,前后交换,说明是升序排列。
举例:判断升序还是降序
-
升序:return this.count > o.count ? 1 : -1; 升序排列 等价于 return this.count - o.count
-
降序:return this.count > o.count ? -1 : 1; 降序排列 等价于 return o.count - this.count
简记:
-
一个入参作减法时:this在前升序,this在后降序
-
两个入参作减法时:o1在前升序,o1在后降序
参考链接:https://donglin.blog.csdn.net/article/details/108176177
2. 数组排序
Arrays常用的方法:
-
static List asList(T...t):创建一个List,将添加多个元素
-
static T binarySearch():二分查找
-
static T[] copyRange(int[], start, end):复制数组
-
static void sort():数据排序
-
static String toString():转化为String
测试代码
package sort; import java.util.*; /** * @ClassName CollectionSortTest01 * @Description TODO * @Author Jiangnan Cui * @Date 2022/11/13 8:45 * @Version 1.0 */ public class CollectionSortTest01 { public static void main(String[] args) { // 字符串类型数组排序测试 stringArraySortTest(); // User类型数组排序测试 ObjectArraySortTest(); } /** * @MethodName stringArraySortTest * @Description 对字符串类型数组中元素进行排序 * 注意:基本类型、String类型底层均已经实现了Comparable接口,所以可以直接使用sort方法,按照默认升序/字符顺序排序 * @Author Jiangnan Cui * @Date 8:57 2022/11/13 */ private static void stringArraySortTest() { String[] stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; System.out.println("原始字符串 = " + Arrays.toString(stringArray)); /** * 输出结果: * [张三, 李四, 王五, 赵六, a, ab, a喜, abc, b, c, d, 喜, 喜a, 喜羊, 喜羊羊] */ /** * 1.通过Array.sort实现字符串数组顺序排列 */ System.out.println("-->1.通过Array.sort实现字符串数组顺序排列"); // 数组默认按字符升序排序 Arrays.sort(stringArray); System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [a, ab, abc, a喜, b, c, d, 喜, 喜a, 喜羊, 喜羊羊, 张三, 李四, 王五, 赵六] * 结果分析: * 数组默认按照字符升序排序,英文字符串按照字母表顺序来,前缀相同时,再依次比较后面的内容 * 中文字符串应该也对应着某种排序规则 * 注意: * 数组排序时,Arrays.sort(stringArray)方法不指定其它条件时,只能实现数组顺序排列,逆序无法实现,因为String内置的排序是按字符顺序排序实现的, * 其它排序规则时需要自己编写方法实现。 */ /** * 2.通过Comparator实现实现字符串数组排序 * 要实现自定义排序器的时候,需要实现该接口: * 当某个类不具备排序功能或者已有的排序功能不足以支撑你需求的时候,可以使用自定义排序, * 比如String内置的排序实现按字符顺序排序,如果想按字符串长度排序就可以自定义实现Comparator的对象。 */ System.out.println("-->2.1 通过Comparator实现实现字符串数组顺序排列"); stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; Comparator upComparator = new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }; Arrays.sort(stringArray, upComparator); System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [a, ab, abc, a喜, b, c, d, 喜, 喜a, 喜羊, 喜羊羊, 张三, 李四, 王五, 赵六] */ System.out.println("---->2.1.1 顺序-使用匿名内部类进行优化"); stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; Arrays.sort(stringArray, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [a, ab, abc, a喜, b, c, d, 喜, 喜a, 喜羊, 喜羊羊, 张三, 李四, 王五, 赵六] */ System.out.println("---->2.1.2 顺序-使用lambmda进行优化"); stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; Arrays.sort(stringArray, ((o1, o2) -> o1.compareTo(o2))); System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [a, ab, abc, a喜, b, c, d, 喜, 喜a, 喜羊, 喜羊羊, 张三, 李四, 王五, 赵六] */ System.out.println("-->2.2 通过Comparator实现实现字符串数组逆序排列"); stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; Comparator downComparator = new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }; Arrays.sort(stringArray,downComparator); System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [赵六, 王五, 李四, 张三, 喜羊羊, 喜羊, 喜a, 喜, d, c, b, a喜, abc, ab, a] */ System.out.println("---->2.2.1 逆序-使用匿名内部类进行优化"); stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; Arrays.sort(stringArray, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }); System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [赵六, 王五, 李四, 张三, 喜羊羊, 喜羊, 喜a, 喜, d, c, b, a喜, abc, ab, a] */ System.out.println("---->2.2.2 逆序-使用lambmda进行优化"); stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; Arrays.sort(stringArray, (o1, o2) -> o2.compareTo(o1)); System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [赵六, 王五, 李四, 张三, 喜羊羊, 喜羊, 喜a, 喜, d, c, b, a喜, abc, ab, a] */ System.out.println("-->2.3 按照字符串长度排序"); System.out.println("---->2.3.1 按照字符串长度升序排列"); stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; Arrays.sort(stringArray, (o1, o2) -> o1.length() - o2.length()); // Arrays.sort(stringArray, (o1, o2) -> o1.length() < o2.length() ? -1 : 1);// 作用同上 // Arrays.sort(stringArray, (o1, o2) -> o1.length() >= o2.length() ? 1 : -1);// 作用同上 System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [a, b, c, d, 喜, 张三, 李四, 王五, 赵六, ab, a喜, 喜a, 喜羊, abc, 喜羊羊] 上下结果有差异??? */ System.out.println("---->2.3.2 按照字符串长度降序排列"); stringArray = new String[]{"张三","李四","王五","赵六","a","ab","a喜","abc","b","c","d","喜","喜a","喜羊","喜羊羊"}; Arrays.sort(stringArray, (o1, o2) -> o2.length() - o1.length()); // Arrays.sort(stringArray, (o1, o2) -> o2.length() < o1.length() ? -1 : 1);// 作用同上 // Arrays.sort(stringArray, (o1, o2) -> o2.length() >= o1.length() ? 1 : -1);// 作用同上 System.out.println("stringArray = " + Arrays.toString(stringArray)); /** * 输出结果: * [abc, 喜羊羊, 张三, 李四, 王五, 赵六, ab, a喜, 喜a, 喜羊, a, b, c, d, 喜] */ } /** * @MethodName ObjectArraySortTest * @Description 对象类型数组排序测试 * @Author Jiangnan Cui * @Date 10:57 2022/11/13 */ private static void ObjectArraySortTest(){ User[] userArray = new User[6];// User类已经实现Comparable接口,定义好比较规则 userArray[0] = new User("张三",10); userArray[1] = new User("李四",20); userArray[2] = new User("王五",30); userArray[3] = new User("zhangsan",10); userArray[4] = new User("lisi",20); userArray[5] = new User("wangwu",30); System.out.println("原始User数组 = " + Arrays.toString(userArray)); /** * 输出结果: * [User{name='张三', age=10}, User{name='李四', age=20}, User{name='王五', age=30}, User{name='zhangsan', age=10}, User{name='lisi', age=20}, User{name='wangwu', age=30}] */ /** * 1.按照年龄大小或姓名字符串长度升降/顺逆序排列 */ System.out.println("--> 1.按照年龄大小升序排列"); Arrays.sort(userArray); System.out.println(Arrays.toString(userArray)); /** * 输出结果: * [User{name='张三', age=10}, User{name='zhangsan', age=10}, User{name='李四', age=20}, User{name='lisi', age=20}, User{name='王五', age=30}, User{name='wangwu', age=30}] */ /** * 2.先按年龄升序排列,再按姓名字符顺序排列 */ userArray = new User[6]; userArray[0] = new User("张三",10); userArray[1] = new User("李四",20); userArray[2] = new User("王五",30); userArray[3] = new User("zhangsan",10); userArray[4] = new User("lisi",20); userArray[5] = new User("wangwu",30); Arrays.sort(userArray,(o1, o2) -> o1.getName().compareTo(o2.getName()));// User类已实现Comparable接口重写public int compareTo(Object o)方法 System.out.println("-->2.先按年龄升序排列,再按姓名字符顺序排列"); System.out.println(Arrays.toString(userArray)); /** * 输出结果: * [User{name='lisi', age=20}, User{name='wangwu', age=30}, User{name='zhangsan', age=10}, User{name='张三', age=10}, User{name='李四', age=20}, User{name='王五', age=30}] */ /** * 3.先按年龄升序排列,再按姓名字符逆序排列 */ userArray = new User[6]; userArray[0] = new User("张三",10); userArray[1] = new User("李四",20); userArray[2] = new User("王五",30); userArray[3] = new User("zhangsan",10); userArray[4] = new User("lisi",20); userArray[5] = new User("wangwu",30); Arrays.sort(userArray,(o1, o2) -> o2.getName().compareTo(o1.getName()));// User类已实现Comparable接口重写public int compareTo(Object o)方法 System.out.println("-->3.先按年龄升序排列,再按姓名字符逆序排列"); System.out.println(Arrays.toString(userArray)); /** * 输出结果: * [User{name='王五', age=30}, User{name='李四', age=20}, User{name='张三', age=10}, User{name='zhangsan', age=10}, User{name='wangwu', age=30}, User{name='lisi', age=20}] */ /** * 4.先按年龄升序排列,再按姓名长度升序排列 */ userArray = new User[6]; userArray[0] = new User("张三",10); userArray[1] = new User("李四",20); userArray[2] = new User("王五",30); userArray[3] = new User("zhangsan",10); userArray[4] = new User("lisi",20); userArray[5] = new User("wangwu",30); Arrays.sort(userArray,(o1, o2) -> o1.getName().length() - o2.getName().length());// User类已实现Comparable接口重写public int compareTo(Object o)方法 System.out.println("--> 4.先按年龄升序排列,再按姓名长度升序排列"); System.out.println(Arrays.toString(userArray)); /** * 输出结果: * [User{name='张三', age=10}, User{name='李四', age=20}, User{name='王五', age=30}, User{name='lisi', age=20}, User{name='wangwu', age=30}, User{name='zhangsan', age=10}] */ /** * 5.先按年龄升序排列,再按姓名长度降序排列 */ userArray = new User[6]; userArray[0] = new User("张三",10); userArray[1] = new User("李四",20); userArray[2] = new User("王五",30); userArray[3] = new User("zhangsan",10); userArray[4] = new User("lisi",20); userArray[5] = new User("wangwu",30); Arrays.sort(userArray,(o1, o2) -> o2.getName().length() - o1.getName().length());// User类已实现Comparable接口重写public int compareTo(Object o)方法 System.out.println("--> 5.先按年龄升序排列,再按姓名长度降序排列"); System.out.println(Arrays.toString(userArray)); /** * 输出结果: * [User{name='zhangsan', age=10}, User{name='wangwu', age=30}, User{name='lisi', age=20}, User{name='张三', age=10}, User{name='李四', age=20}, User{name='王五', age=30}] */ People[] peopleArray = new People[6];// People类未实现Comparable接口 peopleArray[0] = new People("张三",10); peopleArray[1] = new People("李四",20); peopleArray[2] = new People("王五",30); peopleArray[3] = new People("zhangsan",10); peopleArray[4] = new People("lisi",20); peopleArray[5] = new People("wangwu",30); /** * 6.按照年龄升序排列 */ Arrays.sort(peopleArray,(o1, o2) -> o1.getAge() > o2.getAge() ? 1 : -1); System.out.println("-->6.按照年龄升序排列"); System.out.println(Arrays.toString(peopleArray)); /** * 输出结果: * [zhangsan-10, 张三-10, lisi-20, 李四-20, wangwu-30, 王五-30] */ /** * 7.按照年龄降序排列 */ peopleArray = new People[6];// People类未实现Comparable接口 peopleArray[0] = new People("张三",10); peopleArray[1] = new People("李四",20); peopleArray[2] = new People("王五",30); peopleArray[3] = new People("zhangsan",10); peopleArray[4] = new People("lisi",20); peopleArray[5] = new People("wangwu",30); Arrays.sort(peopleArray,(o1, o2) -> o2.getAge() >= o1.getAge() ? 1 : -1); System.out.println("-->7.按照年龄降序排列"); System.out.println(Arrays.toString(peopleArray)); /** * 输出结果: * [王五-30, 李四-20, 张三-10, lisi-20, wangwu-30, zhangsan-10] */ /** * 8.按照姓名长度升序排列 */ peopleArray = new People[6];// People类未实现Comparable接口 peopleArray[0] = new People("张三",10); peopleArray[1] = new People("李四",20); peopleArray[2] = new People("王五",30); peopleArray[3] = new People("zhangsan",10); peopleArray[4] = new People("lisi",20); peopleArray[5] = new People("wangwu",30); Arrays.sort(peopleArray,(o1, o2) -> o1.getName().length() > o2.getName().length() ? 1 : -1); System.out.println("-->8.按照姓名长度升序排列"); System.out.println(Arrays.toString(peopleArray)); /** * 输出结果: * [张三-10, 李四-20, 王五-30, lisi-20, wangwu-30, zhangsan-10] */ /** * 9.按照姓名长度降序排列 */ peopleArray = new People[6];// People类未实现Comparable接口 peopleArray[0] = new People("张三",10); peopleArray[1] = new People("李四",20); peopleArray[2] = new People("王五",30); peopleArray[3] = new People("zhangsan",10); peopleArray[4] = new People("lisi",20); peopleArray[5] = new People("wangwu",30); Arrays.sort(peopleArray,(o1, o2) -> o2.getName().length() >= o1.getName().length() ? 1 : -1); System.out.println("-->9.按照姓名长度降序排列"); System.out.println(Arrays.toString(peopleArray)); /** * 输出结果: * [zhangsan-10, wangwu-30, lisi-20, 张三-10, 李四-20, 王五-30] */ /** * 10.先按照年龄升序,再按照姓名长度升序排列 */ peopleArray = new People[7];// People类未实现Comparable接口 peopleArray[0] = new People("zhangsan",10); peopleArray[1] = new People("zhangsan",20); peopleArray[2] = new People("lisi",20); peopleArray[3] = new People("lisi",30); peopleArray[4] = new People("wangwu",30); peopleArray[5] = new People("wagnwu",40); peopleArray[6] = new People("fighting",40); System.out.println("原始数组:" + Arrays.toString(peopleArray)); /** * [zhangsan-10, zhangsan-20, lisi-20, lisi-30, wangwu-30, wagnwu-40, fighting-40] */ Arrays.sort(peopleArray,(o1, o2) -> o1.getAge() > o2.getAge() ? 1 : -1); Arrays.sort(peopleArray, new Comparator<People>() { @Override public int compare(People o1, People o2) { if(o1.getAge() > o2.getAge()){ return 1; }else if(o1.getAge() < o2.getAge()){ return -1; }else{ return o1.getName().length() - o2.getName().length(); } } }); System.out.println("-->10.先按照年龄升序,再按照姓名长度升序排列"); System.out.println(Arrays.toString(peopleArray)); /** * 输出结果: * [zhangsan-10, lisi-20, zhangsan-20, lisi-30, wangwu-30, wagnwu-40, fighting-40] */ } }
输出结果:
原始字符串 = [张三, 李四, 王五, 赵六, a, ab, a喜, abc, b, c, d, 喜, 喜a, 喜羊, 喜羊羊] -->1.通过Array.sort实现字符串数组顺序排列 stringArray = [a, ab, abc, a喜, b, c, d, 喜, 喜a, 喜羊, 喜羊羊, 张三, 李四, 王五, 赵六] -->2.1 通过Comparator实现实现字符串数组顺序排列 stringArray = [a, ab, abc, a喜, b, c, d, 喜, 喜a, 喜羊, 喜羊羊, 张三, 李四, 王五, 赵六] ---->2.1.1 顺序-使用匿名内部类进行优化 stringArray = [a, ab, abc, a喜, b, c, d, 喜, 喜a, 喜羊, 喜羊羊, 张三, 李四, 王五, 赵六] ---->2.1.2 顺序-使用lambmda进行优化 stringArray = [a, ab, abc, a喜, b, c, d, 喜, 喜a, 喜羊, 喜羊羊, 张三, 李四, 王五, 赵六] -->2.2 通过Comparator实现实现字符串数组逆序排列 stringArray = [赵六, 王五, 李四, 张三, 喜羊羊, 喜羊, 喜a, 喜, d, c, b, a喜, abc, ab, a] ---->2.2.1 逆序-使用匿名内部类进行优化 stringArray = [赵六, 王五, 李四, 张三, 喜羊羊, 喜羊, 喜a, 喜, d, c, b, a喜, abc, ab, a] ---->2.2.2 逆序-使用lambmda进行优化 stringArray = [赵六, 王五, 李四, 张三, 喜羊羊, 喜羊, 喜a, 喜, d, c, b, a喜, abc, ab, a] -->2.3 按照字符串长度排序 ---->2.3.1 按照字符串长度升序排列 stringArray = [a, b, c, d, 喜, 张三, 李四, 王五, 赵六, ab, a喜, 喜a, 喜羊, abc, 喜羊羊] ---->2.3.2 按照字符串长度降序排列 stringArray = [abc, 喜羊羊, 张三, 李四, 王五, 赵六, ab, a喜, 喜a, 喜羊, a, b, c, d, 喜] 原始User数组 = [User{张三-10}, User{李四-20}, User{王五-30}, User{zhangsan-10}, User{lisi-20}, User{wangwu-30}] --> 1.按照年龄大小升序排列 [User{张三-10}, User{zhangsan-10}, User{李四-20}, User{lisi-20}, User{王五-30}, User{wangwu-30}] -->2.先按年龄升序排列,再按姓名字符顺序排列 [User{lisi-20}, User{wangwu-30}, User{zhangsan-10}, User{张三-10}, User{李四-20}, User{王五-30}] -->3.先按年龄升序排列,再按姓名字符逆序排列 [User{王五-30}, User{李四-20}, User{张三-10}, User{zhangsan-10}, User{wangwu-30}, User{lisi-20}] --> 4.先按年龄升序排列,再按姓名长度升序排列 [User{张三-10}, User{李四-20}, User{王五-30}, User{lisi-20}, User{wangwu-30}, User{zhangsan-10}] --> 5.先按年龄升序排列,再按姓名长度降序排列 [User{zhangsan-10}, User{wangwu-30}, User{lisi-20}, User{张三-10}, User{李四-20}, User{王五-30}] -->6.按照年龄升序排列 [People{zhangsan-10}, People{张三-10}, People{lisi-20}, People{李四-20}, People{wangwu-30}, People{王五-30}] -->7.按照年龄降序排列 [People{王五-30}, People{wangwu-30}, People{李四-20}, People{lisi-20}, People{张三-10}, People{zhangsan-10}] -->8.按照姓名长度升序排列 [People{王五-30}, People{李四-20}, People{张三-10}, People{lisi-20}, People{wangwu-30}, People{zhangsan-10}] -->9.按照姓名长度降序排列 [People{zhangsan-10}, People{wangwu-30}, People{lisi-20}, People{张三-10}, People{李四-20}, People{王五-30}] 原始数组:[People{zhangsan-10}, People{zhangsan-20}, People{lisi-20}, People{lisi-30}, People{wangwu-30}, People{wagnwu-40}, People{fighting-40}] -->10.先按照年龄升序,再按照姓名长度升序排列 [People{zhangsan-10}, People{lisi-20}, People{zhangsan-20}, People{lisi-30}, People{wangwu-30}, People{wagnwu-40}, People{fighting-40}]
3. List集合排序
Collections常用的方法:
-
static void sort(List):对List中的元素按自然顺序进行排序
-
static void reverse(List):翻转集合中的元素
-
static void shuffle(List):洗牌(打乱顺序)
-
static E max(Collection):获取集合中最大的元素
-
static E min(Collection):获取集合中最小的元素
-
static void addAll(Collection coll,T...t):向coll中增加多个元素
-
static int binarySearch(List):二分查找
-
static void copy(List desc, List src):复制
测试代码
package sort; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; /** * @ClassName CollectionSortTest2 * @Description TODO * @Author Jiangnan Cui * @Date 2022/11/13 16:27 * @Version 1.0 */ public class CollectionSortTest2 { public static void main(String[] args) { // // 基本类型List排序测试 // basicTypeListSortTest(); // // // String类型List排序测试 // stringTypeListSortTest(); // Object类型List排序测试 objectTypeListSortTest(); } /** * @MethodName basicTypeListSortTest * @Description 基本类型List排序测试,此处以Integer为例 * 注意:基本类型底层已经实现了Comparable接口,可直接利用sort方法进行排序 * @Author Jiangnan Cui * @Date 16:43 2022/11/13 */ private static void basicTypeListSortTest(){ List<Integer> integerList = new ArrayList<>(); integerList.add(1); integerList.add(5); integerList.add(3); integerList.add(4); integerList.add(2); System.out.println("integerList:" + integerList.toString()); /** * 输出结果:[1, 5, 3, 4, 2] */ /** * 1.integerList升序排列 */ Collections.sort(integerList); System.out.println("Collections.sort(integerList):" + integerList.toString()); /** * 输出结果:[1, 2, 3, 4, 5] /** * 2.integerList反转 ≠ 降序排列 */ integerList = new ArrayList<>(); integerList.add(1); integerList.add(5); integerList.add(3); integerList.add(4); integerList.add(2); Collections.reverse(integerList); System.out.println("Collections.reverse(integerList):" + integerList.toString()); /** * 输出结果:[2, 4, 3, 5, 1] */ /** * 3.integerList降序排列 */ integerList = new ArrayList<>(); integerList.add(1); integerList.add(5); integerList.add(3); integerList.add(4); integerList.add(2); Collections.sort(integerList); Collections.reverse(integerList); System.out.println("Collections.sort(integerList); Collections.reverse(integerList);" + integerList.toString()); /** * 输出结果:[5, 4, 3, 2, 1] */ } /** * @MethodName stringTypeListSortTest * @Description String类型List排序测试 * 注意:String类型底层已经实现了Comparable接口,可直接利用sort方法进行排序 * @Author Jiangnan Cui * @Date 16:45 2022/11/13 */ private static void stringTypeListSortTest(){ List<String> stringList = new ArrayList<>(); stringList.add("zhangsan"); stringList.add("lisi"); stringList.add("wangwu"); stringList.add("zhaoliu"); stringList.add("fighting"); System.out.println("stringList:" + stringList.toString()); /** * 输出结果:[zhangsan, lisi, wangwu, zhaoliu, fighting] */ /** * 1.按照字符顺序(即英文字母顺序)排序 */ Collections.sort(stringList); System.out.println("Collections.sort(stringList);" + stringList.toString()); /** * 输出结果:[fighting, lisi, wangwu, zhangsan, zhaoliu] */ /** * 2.逆序输出 */ stringList = new ArrayList<>(); stringList.add("zhangsan"); stringList.add("lisi"); stringList.add("wangwu"); stringList.add("zhaoliu"); stringList.add("fighting"); Collections.reverse(stringList); System.out.println("Collections.reverse(stringList);" + stringList.toString()); /** * 输出结果:[fighting, zhaoliu, wangwu, lisi, zhangsan] */ /** * 3.按照字符串长度排序 */ stringList = new ArrayList<>(); stringList.add("zhangsan"); stringList.add("lisi"); stringList.add("wangwu"); stringList.add("zhaoliu"); stringList.add("fighting"); Collections.sort(stringList,(o1, o2) -> o1.length() > o2.length() ? 1 : -1);// 升序 System.out.println("Collections.sort(stringList,(o1, o2) -> o1.length() > o2.length() ? 1 : -1):" + stringList.toString()); /** * 输出结果:[lisi, wangwu, zhaoliu, fighting, zhangsan] */ stringList = new ArrayList<>(); stringList.add("zhangsan"); stringList.add("lisi"); stringList.add("wangwu"); stringList.add("zhaoliu"); stringList.add("fighting"); Collections.sort(stringList,(o1, o2) -> o1.length() <= o2.length() ? 1 : -1);// 降序 System.out.println("Collections.sort(stringList,(o1, o2) -> o1.length() <= o2.length() ? 1 : -1):" + stringList.toString()); /** * 输出结果:[zhangsan, fighting, zhaoliu, wangwu, lisi] */ } /** * @MethodName objectTypeListSortTest * @Description Object类型List排序测试 * @Author Jiangnan Cui * @Date 17:08 2022/11/13 */ private static void objectTypeListSortTest(){ // User已实现Comparable接口,重写compareTo方法,定义好排序规则 List<User> userList = new ArrayList<>(); userList.add(new User("张三",10)); userList.add(new User("李四",20)); userList.add(new User("王五",30)); userList.add(new User("zhangsan",10)); userList.add(new User("lisi",20)); userList.add(new User("wangwu",30)); System.out.println("userList: " + userList.toString()); /** * 输出结果:[User{张三-10}, User{李四-20}, User{王五-30}, User{zhangsan-10}, User{lisi-20}, User{wangwu-30}] */ /** * 1.通过Comparable实现先按照年龄升序,再按照姓名长度升序 * 注意:使用Comparable接口进行排序时,实体类必须实现该接口,同时重写compareTo方法, * 每次更换排序规则时,都要修改方法实现,使用不方便 */ Collections.sort(userList); System.out.println("Collections.sort(userList): " + userList.toString()); /** * 输出结果:[User{张三-10}, User{zhangsan-10}, User{李四-20}, User{lisi-20}, User{王五-30}, User{wangwu-30}] */ // People未实现Comparable接口 List<People> peopleList = new ArrayList<>(); peopleList.add(new People("张三",10)); peopleList.add(new People("李四",20)); peopleList.add(new People("王五",30)); peopleList.add(new People("zhangsan",10)); peopleList.add(new People("lisi",20)); peopleList.add(new People("wangwu",30)); System.out.println("peopleList: " + peopleList.toString()); /** * 输出结果:[People{张三-10}, People{李四-20}, People{王五-30}, People{zhangsan-10}, People{lisi-20}, People{wangwu-30}] */ /** * 2.通过Comparator接口实现自定义排序 */ System.out.println("-->2.通过Comparator接口实现自定义排序"); Collections.sort(peopleList, (o1, o2) -> o1.getAge() > o2.getAge() ? 1 : -1); // Collections.sort(peopleList, (o1, o2) -> o1.getAge() - o2.getAge()); System.out.println("---->2.1 按照年龄升序排列:" + peopleList.toString()); /** * 输出结果:[People{zhangsan-10}, People{张三-10}, People{lisi-20}, People{李四-20}, People{wangwu-30}, People{王五-30}] */ peopleList = new ArrayList<>(); peopleList.add(new People("张三",10)); peopleList.add(new People("李四",20)); peopleList.add(new People("王五",30)); peopleList.add(new People("zhangsan",10)); peopleList.add(new People("lisi",20)); peopleList.add(new People("wangwu",30)); Collections.sort(peopleList, (o1, o2) -> o2.getAge() >= o1.getAge() ? 1 : -1); // Collections.sort(peopleList, (o1, o2) -> o2.getAge() - o1.getAge()); System.out.println("---->2.2 按照年龄降序排列:" + peopleList.toString()); /** * 输出结果:[People{王五-30}, People{wangwu-30}, People{李四-20}, People{lisi-20}, People{张三-10}, People{zhangsan-10}] */ peopleList = new ArrayList<>(); peopleList.add(new People("张三",10)); peopleList.add(new People("李四",20)); peopleList.add(new People("王五",30)); peopleList.add(new People("zhangsan",10)); peopleList.add(new People("lisi",20)); peopleList.add(new People("wangwu",30)); Collections.sort(peopleList, (o1, o2) -> o1.getName().length() > o2.getName().length() ? 1 : -1); // Collections.sort(peopleList, (o1, o2) -> o1.getName().length() - o2.getName().length(); System.out.println("---->2.3 按照姓名长度升序排列:" + peopleList.toString()); /** * 输出结果:[People{王五-30}, People{李四-20}, People{张三-10}, People{lisi-20}, People{wangwu-30}, People{zhangsan-10}] */ peopleList = new ArrayList<>(); peopleList.add(new People("张三",10)); peopleList.add(new People("李四",20)); peopleList.add(new People("王五",30)); peopleList.add(new People("zhangsan",10)); peopleList.add(new People("lisi",20)); peopleList.add(new People("wangwu",30)); Collections.sort(peopleList, (o1, o2) -> o2.getName().length() >= o1.getName().length() ? 1 : -1); // Collections.sort(peopleList, (o1, o2) -> o2.getName().length()- o1.getName().length()); System.out.println("---->2.4 按照姓名长度降序排列:" + peopleList.toString()); /** * 输出结果:[People{zhangsan-10}, People{wangwu-30}, People{lisi-20}, People{张三-10}, People{李四-20}, People{王五-30}] */ peopleList = new ArrayList<>(); peopleList.add(new People("张三",10)); peopleList.add(new People("李四",20)); peopleList.add(new People("王五",30)); peopleList.add(new People("zhangsan",10)); peopleList.add(new People("lisi",20)); peopleList.add(new People("wangwu",30)); Collections.sort(peopleList, new Comparator<People>() { @Override public int compare(People o1, People o2) { if(o1.getAge() > o2.getAge()){ return 1; }else if(o1.getAge() < o2.getAge()){ return -1; }else{ return o1.getName().length() - o2.getName().length(); } } }); System.out.println("---->2.5 先按照年龄升序排列,再按照姓名长度降序排列:" + peopleList.toString()); /** * 输出结果:[People{张三-10}, People{zhangsan-10}, People{李四-20}, People{lisi-20}, People{王五-30}, People{wangwu-30}] */ /** * 3.使用stream实现 */ peopleList = new ArrayList<>(); peopleList.add(new People("张三",10)); peopleList.add(new People("李四",20)); peopleList.add(new People("王五",30)); peopleList.add(new People("zhangsan",10)); peopleList.add(new People("lisi",20)); peopleList.add(new People("wangwu",30)); // 按照年龄升序排列 List<People> ageSort = peopleList.stream().sorted(Comparator.comparing(People::getAge)).collect(Collectors.toList()); System.out.println("Comparator.comparing(People::getAge):" + ageSort.toString()); /** * 输出结果:[People{张三-10}, People{zhangsan-10}, People{李四-20}, People{lisi-20}, People{王五-30}, People{wangwu-30}] */ // 按照年龄降序1:先以age进行升序,再对升序结果进行age降序 List<People> ageSortReverse = peopleList.stream().sorted(Comparator.comparing(People::getAge).reversed()).collect(Collectors.toList()); System.out.println("Comparator.comparing(People::getAge).reversed():" + ageSortReverse.toString()); /** * 输出结果:[People{王五-30}, People{wangwu-30}, People{李四-20}, People{lisi-20}, People{张三-10}, People{zhangsan-10}] * 降序结果并不是升序结果的直接逆序,有差异 */ // 按照年龄降序2:以age进行降序 List<People> ageSortReverse2 = peopleList.stream().sorted(Comparator.comparing(People::getAge,Comparator.reverseOrder())).collect(Collectors.toList()); System.out.println("Comparator.comparing(People::getAge,Comparator.reverseOrder()):" + ageSortReverse2.toString()); /** * 输出结果:[People{王五-30}, People{wangwu-30}, People{李四-20}, People{lisi-20}, People{张三-10}, People{zhangsan-10}] * 降序结果并不是升序结果的直接逆序,有差异 */ // 先以age进行升序,再以name字符顺序进行排序 List<People> ageNameUpSort = peopleList.stream().sorted(Comparator.comparing(People::getAge).thenComparing(People::getName)).collect(Collectors.toList()); System.out.println("Comparator.comparing(People::getAge).thenComparing(People::getName)):" + ageNameUpSort.toString()); /** * 输出结果:[People{zhangsan-10}, People{张三-10}, People{lisi-20}, People{李四-20}, People{wangwu-30}, People{王五-30}] */ // 先以age进行升序,再对升序结果进行降序,再以name字符顺序进行排序 List<People> ageNameDownSort = peopleList.stream().sorted(Comparator.comparing(People::getAge).reversed().thenComparing(People::getName)).collect(Collectors.toList()); System.out.println("Comparator.comparing(People::getAge).reversed().thenComparing(People::getName)):" + ageNameDownSort.toString()); /** * 输出结果:[People{wangwu-30}, People{王五-30}, People{lisi-20}, People{李四-20}, People{zhangsan-10}, People{张三-10}] */ // 先以age进行降序,再以name字符顺序进行排序 List<People> ageNameDownSort2 = peopleList.stream().sorted(Comparator.comparing(People::getAge,Comparator.reverseOrder()).thenComparing(People::getName)).collect(Collectors.toList()); System.out.println("Comparator.comparing(People::getAge,Comparator.reverseOrder()).reversed().thenComparing(People::getName)):" + ageNameDownSort2.toString()); /** * 输出结果:[People{wangwu-30}, People{王五-30}, People{lisi-20}, People{李四-20}, People{zhangsan-10}, People{张三-10}] */ } }
输出结果:
userList: [User{张三-10}, User{李四-20}, User{王五-30}, User{zhangsan-10}, User{lisi-20}, User{wangwu-30}] Collections.sort(userList): [User{张三-10}, User{zhangsan-10}, User{李四-20}, User{lisi-20}, User{王五-30}, User{wangwu-30}] peopleList: [People{张三-10}, People{李四-20}, People{王五-30}, People{zhangsan-10}, People{lisi-20}, People{wangwu-30}] -->2.通过Comparator接口实现自定义排序 ---->2.1 按照年龄升序排列:[People{zhangsan-10}, People{张三-10}, People{lisi-20}, People{李四-20}, People{wangwu-30}, People{王五-30}] ---->2.2 按照年龄降序排列:[People{王五-30}, People{wangwu-30}, People{李四-20}, People{lisi-20}, People{张三-10}, People{zhangsan-10}] ---->2.3 按照姓名长度升序排列:[People{王五-30}, People{李四-20}, People{张三-10}, People{lisi-20}, People{wangwu-30}, People{zhangsan-10}] ---->2.4 按照姓名长度降序排列:[People{zhangsan-10}, People{wangwu-30}, People{lisi-20}, People{张三-10}, People{李四-20}, People{王五-30}] ---->2.5 先按照年龄升序排列,再按照姓名长度降序排列:[People{张三-10}, People{zhangsan-10}, People{李四-20}, People{lisi-20}, People{王五-30}, People{wangwu-30}] Comparator.comparing(People::getAge):[People{张三-10}, People{zhangsan-10}, People{李四-20}, People{lisi-20}, People{王五-30}, People{wangwu-30}] Comparator.comparing(People::getAge).reversed():[People{王五-30}, People{wangwu-30}, People{李四-20}, People{lisi-20}, People{张三-10}, People{zhangsan-10}] Comparator.comparing(People::getAge,Comparator.reverseOrder()):[People{王五-30}, People{wangwu-30}, People{李四-20}, People{lisi-20}, People{张三-10}, People{zhangsan-10}] Comparator.comparing(People::getAge).thenComparing(People::getName)):[People{zhangsan-10}, People{张三-10}, People{lisi-20}, People{李四-20}, People{wangwu-30}, People{王五-30}] Comparator.comparing(People::getAge).reversed().thenComparing(People::getName)):[People{wangwu-30}, People{王五-30}, People{lisi-20}, People{李四-20}, People{zhangsan-10}, People{张三-10}] Comparator.comparing(People::getAge,Comparator.reverseOrder()).reversed().thenComparing(People::getName)):[People{wangwu-30}, People{王五-30}, People{lisi-20}, People{李四-20}, People{zhangsan-10}, People{张三-10}]
总结:
list.stream().sorted单属性排序
-
Comparator.comparing(类::属性一).reversed():是得到排序结果后再排序
-
Comparator.comparing(类::属性一,Comparator.reverseOrder()):是直接进行排序,建议使用后者
list.stream().sorted多属性排序
list.stream().sorted(Comparator.comparing(类::属性一).thenComparing(类::属性二));
4. 使用一个List给另一个List排序
参考链接:Java 两个List按照其中一个List元素顺序对另一个List元素进行排序_菜菌的博客-CSDN博客_list按照某个list排序
package sort; import java.util.Arrays; import java.util.HashMap; import java.util.List; /** * @ClassName CollectionSortTest03 * @Description TODO * @Author Jiangnan Cui * @Date 2022/11/13 19:23 * @Version 1.0 */ public class CollectionSortTest03 { public static void main(String[] args) { List<String> orderList = Arrays.asList("1", "2", "3", "4", "5"); List<String> targetList = Arrays.asList("5", "1", "3", "7", "2", "6", "4"); sortList(orderList,targetList); System.out.println(targetList.toString());// [1, 2, 3, 4, 5, 7, 6] targetList = Arrays.asList("5", "1", "3", "7", "2", "6", "4"); sortList2(orderList,targetList); System.out.println(targetList.toString());// [7, 6, 1, 2, 3, 4, 5] targetList = Arrays.asList("5", "1", "3", "7", "2", "6", "4"); sortList3(orderList,targetList); System.out.println(targetList.toString());// [7, 6, 1, 2, 3, 4, 5] } /** * @MethodName sortList * @Description 利用一个List给另一个List进行排序 * @param: orderList 已经排好序的集合-基准集合 * @param: targetList 待排序集合-目标集合 * orderList不存在的元素放置在targetList的最后面 * @Author Jiangnan Cui * @Date 19:26 2022/11/13 */ private static void sortList(List<String> orderList, List<String> targetList){ // 遍历targetList中的元素进行排序 targetList.sort((o1, o2) -> { // 在orderList中查找是否存在该元素,存在时返回索引下标,不存在时返回-1 int index1 = orderList.indexOf(o1); int index2 = orderList.indexOf(o2); // orderList中包含o1 if(index1 != -1){ index1 = targetList.size() - index1; } // orderList中包含o2 if(index2 != -1){ index2 = targetList.size() - index2; } return index2 - index1; }); } /** * @MethodName sortList2 * @Description 利用一个List给另一个List进行排序 * @param: orderList 已经排好序的集合-基准集合 * @param: targetList 待排序集合-目标集合 * orderList不存在的元素放置在targetList的最前面 * @Author Jiangnan Cui * @Date 19:26 2022/11/13 */ private static void sortList2(List<String> orderList, List<String> targetList){ // 遍历targetList中的元素进行排序 targetList.sort((o1, o2) -> { // 在orderList中查找是否存在该元素,存在时返回索引下标,不存在时返回-1 int index1 = orderList.indexOf(o1); int index2 = orderList.indexOf(o2); return index1 - index2; }); } /** * @MethodName sortList3 * @Description 利用一个List给另一个List进行排序 * @param: orderList 已经排好序的集合-基准集合 * @param: targetList 待排序集合-目标集合 * orderList不存在的元素放置在targetList的最前面 * @Author Jiangnan Cui * @Date 19:26 2022/11/13 */ private static void sortList3(List<String> orderList, List<String> targetList){ // 以orderList中每个元素记作key,value用于记录该元素出现的先后次序 HashMap<String, Integer> indexMap = new HashMap<>(); for (int i = 0; i < orderList.size(); i++) { indexMap.put(orderList.get(i),i); } // 遍历targetList中的元素进行排序 targetList.sort((o1, o2) -> { // 在indexMap中查找是否存在该元素,存在时返回对应value,不存在时返回null Integer index1 = indexMap.get(o1); Integer index2 = indexMap.get(o2); // 两个元素均不存在 if(index1 == null && index2 == null){ return 0; } // 有一个存在,有一个不存在 if(index1 != null ^ index2 != null){ return index1 == null ? -1 : 1;// 不存在的放前面,存在的放后面 } // 两个都存在 return index1 - index2;// 升序排列 }); } }
输出结果:
[1, 2, 3, 4, 5, 7, 6] [7, 6, 1, 2, 3, 4, 5] [7, 6, 1, 2, 3, 4, 5]