题目依托
本题来自2022年蓝桥杯省赛第一场题目:
解法
构建num类,包含数值的大小和各位数字之和;用 Vector 保存 n 个 num 对象,利用Coolections.sort() 重写排序,实现题解。
Java 代码如下 :
package com.lanqiao;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Vector;
public class QuestionD {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //获取输入的n和m
int m = sc.nextInt();
//判断n=1的情况,只输入一个数
if (n == 1) {
System.out.println(1);
}
//创建一个Vector容器,相当于动态数组,元素是num类
Vector<num> nums = new Vector<>();
//将所有数据都加入到nums中
for (int i = 1; i <= n; i++) {
nums.addElement(new num(i, num.sum(i)));;
}
//重写排序
Collections.sort(nums, new Comparator<num>() {
@Override
public int compare(num o1, num o2) {
// TODO Auto-generated method stub
if (o1.ans == o2.ans) {
return o1.val > o2.val ? 1 : -1;
} else {
return o1.ans > o2.ans ? 1 : -1;
}
}
});
//获取第m位元素的数值
System.out.println(nums.elementAt(m - 1).val);
sc.close();
}
//包含数字和各位数字之和的类
public static class num {
int val;
int ans;
public num(int val, int ans) {
this.val = val;
this.ans = ans;
}
public static int sum(int val) {
int ans = 0;
while (val > 0) {
ans += val % 10;
val /= 10;
}
return ans;
}
}
}
测试结果
Collections.sort() 详解
Comparable接口
对于放在如 Map, Set, List 等集合中的数据,要对他们进行排序的话,可以利用其提供的 sort() 排序方法 ,对数据排序直接使用这个方法,但是要保证集合中的对象是可比较的。
要让对象可比较,就需要该对象实现 Comparable 接口,然后重写里面的compareTo()方法。
假设有一个学生类,默认需要按学生的年龄字段 age 进行排序代码如下:
public class Student implements Comparable<Student> {
private int id;
private int age;
private String name;
public Student(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
@Override
public int compareTo(Student o) {
//降序
//return o.age - this.age;
//升序
return this.age - o.age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
重写的 public int compareTo(Student o){} 这个方法,它返回三种 int 类型的值: 负整数,零 ,正整数。
示例代码
public static void main(String args[]){
List<Student> list = new ArrayList<>();
list.add(new Student(1,25,"关羽"));
list.add(new Student(2,21,"张飞"));
list.add(new Student(3,18,"刘备"));
list.add(new Student(4,32,"袁绍"));
list.add(new Student(5,36,"赵云"));
list.add(new Student(6,16,"曹操"));
System.out.println("排序前:");
for (Student student : list) {
System.out.println(student.toString());
}
//使用默认排序
Collections.sort(list);
System.out.println("默认排序后:");
for (Student student : list) {
System.out.println(student.toString());
}
}
测试结果
排序前:
Student{id=1, age=25, name='关羽'}
Student{id=2, age=21, name='张飞'}
Student{id=3, age=18, name='刘备'}
Student{id=4, age=32, name='袁绍'}
Student{id=5, age=36, name='赵云'}
Student{id=6, age=16, name='曹操'}
默认排序后:
Student{id=6, age=16, name='曹操'}
Student{id=3, age=18, name='刘备'}
Student{id=2, age=21, name='张飞'}
Student{id=1, age=25, name='关羽'}
Student{id=4, age=32, name='袁绍'}
Student{id=5, age=36, name='赵云'}
Comparator接口
有时候可能要考虑到对两个属性进行排序,比如上面示例中再对 id 排序,再入开篇题解中不光要考虑数值的大小,还要考虑各位数之和,这就需要使用比较器 Comparator。
Comparator 的使用有两种方式:
- Collections.sort(list,Comparator);
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() - o2.getId();
}
});
开篇的题解中就是采用了这个写法。
compare(Student o1, Student o2) 方法的返回值跟 Comparable<> 接口中的 compareTo(Student o) 方法 返回值意思相同。
- list.sort(Comparator);
list.sort(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() - o2.getId();
}
});