list集合的几种排序方式:
1、Collections.sort(list<基本类型>)
List<Integer> list = new ArrayList<>();
list.add(3);
list.add(5);
list.add(1);
Collections工具类,升序排:
Collections.sort(list);
System.out.println(list);
Collections工具类,降序排:
Collections.reverse(list);
System.out.println(list);
1.1Collections.sort(list<基本类型>) 使用java8
list.sort(Integer::compareTo);
System.out.println(list);
2、Collections.sort(list<字符串>)
public void printListStringSort(){
List<String> list = new ArrayList<String>();
list.add("15");
list.add("123");
list.add("10");
list.add("9");
list.add("3");
System.out.println( "---------------升序排列----------------" );
// 升序排列
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int num1 = Integer.parseInt(o1);
int num2 = Integer.parseInt(o2);
if (num1 > num2) {
return 1;
} else if (num1 < num2) {
return -1;
} else {
return 0;
}
}
});
for (String str : list) {
System.out.println(str);
}
System.out.println( "---------------降序排列----------------" );
// 降序排列
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int num1 = Integer.parseInt(o1);
int num2 = Integer.parseInt(o2);
if (num1 < num2) {
return 1;
} else if (num1 > num2) {
return -1;
} else {
return 0;
}
}
});
for (String str : list) {
System.out.println(str);
}
}
3、Collections.sort(java对象)
这种方式需要满足以下条件:
1.1、list集合中元素的数据类型是一个java对象;
1.2、该java对象必须实现Comparable类;
1.3、重写compareTo方法;
其中 compareTo 方法用于指示当前元素与其他元素的比较规则,一般都是以 a - b 的形式返回int类型,表示排序规则为从 a 到 b 排序,其逻辑理解就是:如果compareTo方法返回值小于0,则当前元素往前放,大于0,则往后放。
Student实体类:
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Student implements Comparable<Student> {
private String name;
private int age;
@Override
public int compareTo(Student stu) {
return getAge() - stu.getAge();
}
}
测试:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestUtil {
public static void main(String[] args) {
Student stu1=new Student("小米",1);
Student stu2=new Student("小王",2);
Student stu3=new Student("小明",3);
List<Student> list=new ArrayList<>();
list.add(stu2);
list.add(stu1);
list.add(stu3);
System.out.println("排序前:");
System.out.println(list);
System.out.println("排序后:");
Collections.sort(list);
System.out.println(list);
}
}
4、Collections.sort(java对象集合, new Comparator<>() {});
这种方式与需要满足以下条件:
1.1、list集合中元素的数据类型是一个java对象;
1.2、重写compare方法;
Comparator 和 Comparable 的区别和理解:
Comparator 可以看成是外部比较器,因为它是先有list集合,然后再对list集合用比较器去排序;
Comparable 可以看成是内部比较器,因为它是直接在java对象实现类添加了比较器,因此是先有比较器,然后再对list集合用比较器去排序;
从上面两点,也可以推测出 Comparable 的排序算法的效率应该是比 Comparator 要高效的。
Comparator :使用了匿名内部类来构建了一个Comparator比较器对象,从而实现排序,优点是:不需要在创建java对象时,实现 Comparable 接口,缺点是效率比 Comparable 要低一些。
Student实体类:
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Student{
private String name;
private int age;
}
测试:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestUtil {
public static void main(String[] args) {
Student stu1 = new Student("小米", 1);
Student stu2 = new Student("小王", 2);
Student stu3 = new Student("小明", 3);
List<Student> list = new ArrayList<>();
list.add(stu2);
list.add(stu1);
list.add(stu3);
System.out.println("排序前:");
System.out.println(list);
System.out.println("排序后:");
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student stu1, Student stu2) {
return stu1.getAge() - stu2.getAge();
}
});
System.out.println(list);
}
}
4.1根据 JAVA8 的 lambda 表达式
上面Compartor比较器的代码可以简写成以下代码:
Collections.sort(list, (stu11, stu21) -> stu11.getAge() - stu21.getAge());
再进一步简化成如下代码:
Collections.sort(list, Comparator.comparingInt(Student::getAge));
或
Collections.sort(list, Comparator.comparing(Student::getAge));
通过查询 comparing开头的方法,可以看见:
经过测试发现comparing兼容了下面三种基于整型数据的方法:
显然用comparing很省事,但是一般兼容性越高,效率也就越低,可以推测出comparing方法内部肯定是有一重判断了参数的数据类型的逻辑,这会降低代码执行效率;因此,如果是整型数据的话,建议使用上面三种与数据类型对应的方法,而如果是字符串的话,就使用comparing。
简化后:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestUtil {
public static void main(String[] args) {
Student stu1 = new Student("小米", 1);
Student stu2 = new Student("小王", 2);
Student stu3 = new Student("小明", 3);
List<Student> list = new ArrayList<>();
list.add(stu2);
list.add(stu1);
list.add(stu3);
System.out.println("排序前:");
System.out.println(list);
System.out.println("排序后:");
Collections.sort(list, Comparator.comparingInt(Student::getAge));
System.out.println(list);
}
}
可以看出这是升序排序的,那么如何降序呢?
由于降序=升序的倒序,所以可以使用倒序的方法【.reversed()】实现降序:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestUtil {
public static void main(String[] args) {
Student stu1 = new Student("小米", 1);
Student stu2 = new Student("小王", 2);
Student stu3 = new Student("小明", 3);
List<Student> list = new ArrayList<>();
list.add(stu2);
list.add(stu1);
list.add(stu3);
System.out.println("排序前:");
System.out.println(list);
System.out.println("排序后:");
Collections.sort(list, Comparator.comparingInt(Student::getAge));
System.out.println(list);
System.out.println("倒序后:");
Collections.sort(list, Comparator.comparingInt(Student::getAge).reversed());
System.out.println(list);
}
}
多条件排序:
Student实体类:
@Data
@AllArgsConstructor
public class Student{
private String name;
private int age;
private double grade;
private int tall;
}
测试:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestUtil {
public static void main(String[] args) {
Student stu1 = new Student("小米", 20, 95.0, 175);
Student stu2 = new Student("小王", 20, 90.5, 175);
Student stu3 = new Student("小明", 20, 90.0, 180);
List<Student> list = new ArrayList<>();
list.add(stu2);
list.add(stu1);
list.add(stu3);
System.out.println("排序前:");
System.out.println(list);
System.out.println("排序后:");
Collections.sort(list, Comparator.comparingInt(Student::getTall));
System.out.println(list);
System.out.println("倒序后:");
Collections.sort(list, Comparator.comparingInt(Student::getTall).reversed());
System.out.println(list);
System.out.println("1.按年龄升序、分数升序、身高升序排序:");
Collections.sort(list, Comparator.comparingInt(Student::getAge).thenComparingDouble(Student::getGrade).thenComparingInt(Student::getTall));
System.out.println(list);
System.out.println("2.按年龄升序、分数升序、身高降序序排序:");
Collections.sort(list, Comparator.comparingInt(Student::getAge).thenComparingDouble(Student::getGrade).thenComparingInt(Student::getTall).reversed());
System.out.println(list);
System.out.println("3.按年龄升序、分数降序、身高升序排序:");
Collections.sort(list, Comparator.comparingInt(Student::getAge).thenComparingDouble(Student::getGrade).reversed().thenComparingInt(Student::getTall));
System.out.println(list);
System.out.println("4.按年龄升序、分数降序、身高降序序排序:");
Collections.sort(list, Comparator.comparingInt(Student::getAge).thenComparingDouble(Student::getGrade).reversed().thenComparingInt(Student::getTall).reversed());
System.out.println(list);
System.out.println("5.按年龄升序、身高升序、分数升序排序:");
Collections.sort(list, Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTall).thenComparingDouble(Student::getGrade));
System.out.println(list);
System.out.println("6.按年龄升序、身高升序、分数降序序排序:");
Collections.sort(list, Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTall).thenComparingDouble(Student::getGrade).reversed());
System.out.println(list);
System.out.println("7.按年龄升序、身高降序、分数升序排序:");
Collections.sort(list, Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTall).reversed().thenComparingDouble(Student::getGrade));
System.out.println(list);
System.out.println("8.按年龄升序、身高降序、分数降序序排序:");
Collections.sort(list, Comparator.comparing(Student::getAge).thenComparing(Student::getGrade).reversed().thenComparing(Student::getTall).reversed());
System.out.println(list);
}
}
5、list.stream().sorted()
JAVA8 之后,引入了stream流操作,可以极大提高集合的链式操作效率,关于stream流操作不太清楚的小伙伴,可以自行查阅资料;
stream流操作中的 sorted()方法可以用于排序,其逻辑原理和上面第二种 Comparator 的排序方式是一样的。
这种方式与需要满足以下条件:
1.1、list集合中元素的数据类型是一个java对象;
1.2、引入stream流操作规范;
优点:排序算法效率高。
Student实体类:
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Student{
private String name;
private int age;
}
测试:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class TestUtil {
public static void main(String[] args) {
Student stu1 = new Student("小米", 1);
Student stu2 = new Student("小王", 2);
Student stu3 = new Student("小明", 3);
List<Student> list = new ArrayList<>();
list.add(stu2);
list.add(stu1);
list.add(stu3);
System.out.println("排序前:");
System.out.println(list);
System.out.println("排序后:");
list = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
System.out.println(list);
}
}
同样的以使用倒序的方法
【.reversed()】实现降序
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class TestUtil {
public static void main(String[] args) {
Student stu1 = new Student("小米", 1);
Student stu2 = new Student("小王", 2);
Student stu3 = new Student("小明", 3);
List<Student> list = new ArrayList<>();
list.add(stu2);
list.add(stu1);
list.add(stu3);
System.out.println("排序前:");
System.out.println(list);
System.out.println("排序后:");
list = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
System.out.println(list);
System.out.println("倒序后:");
list = list.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());
System.out.println(list);
}
}
多条件排序:
Student实体类:
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Student{
private String name;
private int age;
private double grade;
private int tall;
}
测试:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class TestUtil {
public static void main(String[] args) {
Student stu1 = new Student("小米", 20, 95.0, 175);
Student stu2 = new Student("小王", 20, 90.5, 175);
Student stu3 = new Student("小明", 20, 90.0, 180);
List<Student> list = new ArrayList<>();
list.add(stu2);
list.add(stu1);
list.add(stu3);
System.out.println("排序前:");
System.out.println(list);
System.out.println("1.按年龄升序、分数升序、身高升序排序:");
list = list.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingDouble(Student::getGrade).thenComparingInt(Student::getTall)).collect(Collectors.toList());
System.out.println(list);
System.out.println("2.按年龄升序、分数升序、身高降序序排序:");
list = list.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingDouble(Student::getGrade).thenComparingInt(Student::getTall).reversed()).collect(Collectors.toList());
System.out.println(list);
System.out.println("3.按年龄升序、分数降序、身高升序排序:");
list = list.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingDouble(Student::getGrade).reversed().thenComparingInt(Student::getTall)).collect(Collectors.toList());
System.out.println(list);
System.out.println("4.按年龄升序、分数降序、身高降序序排序:");
list = list.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingDouble(Student::getGrade).reversed().thenComparingInt(Student::getTall).reversed()).collect(Collectors.toList());
System.out.println(list);
System.out.println("5.按年龄升序、身高升序、分数升序排序:");
list = list.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTall).thenComparingDouble(Student::getGrade)).collect(Collectors.toList());
System.out.println(list);
System.out.println("6.按年龄升序、身高升序、分数降序序排序:");
list = list.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTall).thenComparingDouble(Student::getGrade).reversed()).collect(Collectors.toList());
System.out.println(list);
System.out.println("7.按年龄升序、身高降序、分数升序排序:");
list = list.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTall).reversed().thenComparingDouble(Student::getGrade)).collect(Collectors.toList());
System.out.println(list);
System.out.println("8.按年龄升序、身高降序、分数降序序排序:");
list = list.stream().sorted(Comparator.comparingInt(Student::getAge).thenComparingInt(Student::getTall).reversed().thenComparingDouble(Student::getGrade).reversed()).collect(Collectors.toList());
System.out.println(list);
}
}
推荐使用java8流操作排序方法,因为stream流操作排序效率最高。