import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
class Student {
private String name;
private double score;
private int age;
private int index;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, double score, int age) {
this.name = name;
this.score = score;
this.age = age;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
", age=" + age +
", index=" + index +
'}';
}
}
class TestDemo {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("Jack", 52, 10),
new Student("Amdy", 79.5, 10),
new Student("Lucy", 68, 9),
new Student("Tom", 79.5, 11),
new Student("Jerry", 52, 8),
new Student("Cherry", 79.5, 10),
new Student("Sweet", 91, 12),
new Student("Lucky", 68, 9),
new Student("Sim", 79.5, 10),
new Student("Solem", 65, 10)
);
// fun1(students);
// System.out.println("---------------分割线---------------------");
// fun2(students);
// System.out.println("---------------分割线---------------------");
// fun3(students);
// System.out.println("---------------分割线---------------------");
func4(students);
}
/**
* 按照成绩排序 ---低级写法
*/
public static void fun1(List<Student> students) {
students.sort((s1, s2) -> -Double.compare(s1.getScore(), s2.getScore()));
int index = 0;
double lastScore = -1;
for (Student s : students) {
if (Double.compare(lastScore, s.getScore()) != 0) {
lastScore = s.getScore();
index++;
}
System.out.println("名次:" + index + "\t分数" + s.getScore() + "\t名字" + s.getName());
}
}
/**
* 按照成绩排序 --- 使用Java 8
*/
public static void fun2(List<Student> students) {
List<Entry<Double, List<Student>>> list = students.stream()
.collect(Collectors.groupingBy(Student::getScore))
.entrySet()
.stream()
.sorted((s1, s2) -> -Double.compare(s1.getKey(), s2.getKey()))
.collect(Collectors.toList());
int index = 1;
for (Entry<Double, List<Student>> entry : list) {
System.out.print("名次:" + index + "\t分数:" + entry.getKey() + "\t名字");
entry.getValue().forEach((s) -> System.out.print(" " + s.getName()));
System.out.println();
index++;
}
}
/**
* 按照成绩排序 --- 使用Java 8;并列排名跳到下一名
*/
public static void fun3(List<Student> students) {
List<Entry<Double, List<Student>>> list = students.stream()
.collect(Collectors.groupingBy(Student::getScore))
.entrySet()
.stream()
.sorted((s1, s2) -> -Double.compare(s1.getKey(), s2.getKey()))
.collect(Collectors.toList());
int index = 1;
for (Entry<Double, List<Student>> entry : list) {
System.out.print("名次:" + index + "\t分数:" + entry.getKey() + "\t名字");
entry.getValue().forEach((s) -> System.out.print(" " + s.getName()));
System.out.println();
index = index + entry.getValue().size();
}
}
/**
* 按照多条件排序 --- 使用Java 8;并列排名跳到下一名
*/
public static void func4(List<Student> students) {
// students.sort((h1, h2) -> {
// // 排名相同,年龄正序排序
// if (Double.compare(h1.getScore(), h2.getScore()) == 0) {
// return Double.compare(h1.getAge(), h2.getAge());
// }
// return -Double.compare(h1.getScore(), h2.getScore());
// });
students.sort(Comparator.comparing(Student::getScore).reversed().thenComparing(Student::getAge));
// students.forEach(System.out::println);
int index = 0;
int count = 0;
double lastScore = -1;
Map<Integer, Student> rankMap = new HashMap<>(5);
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
System.out.println(s.toString() + ",lastScore:" + lastScore + ",count:" + count + ",index:" + index);
// 如果成绩和上一名的成绩不相同,那么排名+1
if (Double.compare(lastScore, s.getScore()) != 0) {
lastScore = s.getScore();
index = index + 1 + count;
count = 0;
} else {
// 分数相同,如果年龄不同,排名+1
if (Double.compare(students.get(i - 1).getAge(), s.getAge()) != 0) {
index = index + 1 + count;
count = 0;
} else {
// 重复数+1
count++;
}
}
s.setIndex(index);
System.out.println(s.toString() + ",lastScore:" + lastScore + ",count:" + count + ",index:" + index);
System.out.println("****************");
rankMap.put(i, s);
}
for (Integer key : rankMap.keySet()) {
System.out.println(rankMap.get(key));
}
}
}
最后面贴出并列排名跳到下一名的运行结果,index即是各个学生的排名。

其实如果List<Student> students参数是从数据库中读取的,可以通过sql进行一遍排序,
select name, score, age from tb_student order by score desc,age asc;
来替代java排序
students.sort(Comparator.comparing(Student::getScore).reversed().thenComparing(Student::getAge));
然后代码里面不再排序,只做并列排名计算名次跳到下一名的特殊处理。
网友评论