Java 按多个字段对对象列表进行排序
我有一个Java对象列表,我想根据多个字段进行排序Java 按多个字段对对象列表进行排序,java,sorting,collections,Java,Sorting,Collections,我有一个Java对象列表,我想根据多个字段进行排序 public class graduationCeremony { String campus; String faculty; String building; } 是否可以使用比较器或可比界面根据多个字段对列表进行排序?我看到的所有示例都只根据一个字段排序。换句话说,可以按“校园”、“教员”或“建筑”进行分类。我想按“校园”排序,然后按“教员”排序,然后按“建筑”排序(正如SQL中存在的那样:按校园、教员、建筑排序
public class graduationCeremony {
String campus;
String faculty;
String building;
}
是否可以使用比较器
或可比
界面根据多个字段对列表进行排序?我看到的所有示例都只根据一个字段排序。换句话说,可以按“校园”、“教员”或“建筑”进行分类。我想按“校园”排序,然后按“教员”排序,然后按“建筑”排序(正如SQL中存在的那样:按校园、教员、建筑排序
)
我想这个问题已经解决了,但我不明白大家所接受的答案。有人能详细说明这个答案吗?希望这有助于:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
class Person implements Comparable {
String firstName, lastName;
public Person(String f, String l) {
this.firstName = f;
this.lastName = l;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String toString() {
return "[ firstname=" + firstName + ",lastname=" + lastName + "]";
}
public int compareTo(Object obj) {
Person emp = (Person) obj;
int deptComp = firstName.compareTo(emp.getFirstName());
return ((deptComp == 0) ? lastName.compareTo(emp.getLastName()) : deptComp);
}
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person emp = (Person) obj;
return firstName.equals(emp.getFirstName()) && lastName.equals(emp.getLastName());
}
}
class PersonComparator implements Comparator<Person> {
public int compare(Person emp1, Person emp2) {
int nameComp = emp1.getLastName().compareTo(emp2.getLastName());
return ((nameComp == 0) ? emp1.getFirstName().compareTo(emp2.getFirstName()) : nameComp);
}
}
public class Main {
public static void main(String args[]) {
ArrayList<Person> names = new ArrayList<Person>();
names.add(new Person("E", "T"));
names.add(new Person("A", "G"));
names.add(new Person("B", "H"));
names.add(new Person("C", "J"));
Iterator iter1 = names.iterator();
while (iter1.hasNext()) {
System.out.println(iter1.next());
}
Collections.sort(names, new PersonComparator());
Iterator iter2 = names.iterator();
while (iter2.hasNext()) {
System.out.println(iter2.next());
}
}
}
import java.util.ArrayList;
导入java.util.Collections;
导入java.util.Comparator;
导入java.util.Iterator;
类人实现可比性{
字符串firstName,lastName;
公众人物(字符串f、字符串l){
this.firstName=f;
this.lastName=l;
}
公共字符串getFirstName(){
返回名字;
}
公共字符串getLastName(){
返回姓氏;
}
公共字符串toString(){
返回“[firstname=“+firstname+”,lastname=“+lastname+”]”;
}
公共整数比较(对象对象对象){
人员emp=(人员)obj;
int deptComp=firstName.compareTo(emp.getFirstName());
返回((deptComp==0)?lastName.compareTo(emp.getLastName()):deptComp);
}
公共布尔等于(对象obj){
如果(!(人的obj实例)){
返回false;
}
人员emp=(人员)obj;
返回firstName.equals(emp.getFirstName())和&lastName.equals(emp.getLastName());
}
}
类PersonComparator实现Comparator{
公共整数比较(个人emp1,个人emp2){
int-nameComp=emp1.getLastName().compareTo(emp2.getLastName());
返回((nameComp==0)?emp1.getFirstName().compareTo(emp2.getFirstName()):nameComp);
}
}
公共班机{
公共静态void main(字符串参数[]){
ArrayList name=新的ArrayList();
姓名。添加(新人员(“E”、“T”);
姓名。添加(新人员(“A”、“G”);
姓名。添加(新人员(“B”、“H”);
姓名。添加(新人员(“C”、“J”);
迭代器iter1=names.Iterator();
while(iter1.hasNext()){
System.out.println(iter1.next());
}
Collections.sort(name,newpersoncomparator());
迭代器iter2=names.Iterator();
while(iter2.hasNext()){
System.out.println(iter2.next());
}
}
}
您的比较器如下所示:
public class GraduationCeremonyComparator implements Comparator<GraduationCeremony> {
public int compare(GraduationCeremony o1, GraduationCeremony o2) {
int value1 = o1.campus.compareTo(o2.campus);
if (value1 == 0) {
int value2 = o1.faculty.compareTo(o2.faculty);
if (value2 == 0) {
return o1.building.compareTo(o2.building);
} else {
return value2;
}
}
return value1;
}
}
公共类毕业典礼Comparator实现Comparator{
公共int比较(毕业典礼o1,毕业典礼o2){
int value1=o1.campus.compareTo(o2.campus);
如果(值1==0){
int value2=o1.能力比(o2.能力);
如果(值2==0){
返回o1.建筑物。比较(o2.建筑物);
}否则{
返回值2;
}
}
返回值1;
}
}
基本上,只要到目前为止比较的属性相等(
==0
),它就会继续比较类的每个连续属性。是的,您完全可以这样做。例如:
public class PersonComparator implements Comparator<Person>
{
public int compare(Person p1, Person p2)
{
// Assume no nulls, and simple ordinal comparisons
// First by campus - stop if this gives a result.
int campusResult = p1.getCampus().compareTo(p2.getCampus());
if (campusResult != 0)
{
return campusResult;
}
// Next by faculty
int facultyResult = p1.getFaculty().compareTo(p2.getFaculty());
if (facultyResult != 0)
{
return facultyResult;
}
// Finally by building
return p1.getBuilding().compareTo(p2.getBuilding());
}
}
公共类PersonComparator实现Comparator
{
公共整数比较(人员p1、人员p2)
{
//假设没有空值和简单的顺序比较
//首先是校园——如果有结果就停止。
int-campusResult=p1.getCampus().compareTo(p2.getCampus());
如果(campusResult!=0)
{
返回campusResult;
}
//下一位是教员
int facultyResult=p1.getFaculty().compareTo(p2.getFaculty());
如果(faultyresult!=0)
{
返回facultyResult;
}
//最后通过构建
返回p1.getBuilding().compareTo(p2.getBuilding());
}
}
基本上你是说,“如果我能通过观察校园(在他们来自不同的校园之前,校园是最重要的领域)来判断哪一个是第一位的,那么我只会返回结果。否则,我会继续比较各系。再次,如果这足以区分他们,请停止。否则,(如果两个人的校园和教员都相同)只需通过构建来比较他们的结果。”您只需要让您的类继承自
然后以您喜欢的方式实现该方法。您必须编写自己的compareTo()方法,该方法包含执行比较所需的Java代码 例如,如果我们想比较两个公共领域,校园,然后是教员,我们可以做如下操作:
int compareTo(GraduationCeremony gc)
{
int c = this.campus.compareTo(gc.campus);
if( c != 0 )
{
//sort by campus if we can
return c;
}
else
{
//campus equal, so sort by faculty
return this.faculty.compareTo(gc.faculty);
}
}
这很简单,但希望能给你一个想法。有关更多信息,请查阅Comparable和Comparator文档。如果你事先知道使用哪些字段进行比较,那么其他人会给出正确的答案。
您可能感兴趣的是对集合进行排序,以防在编译时不知道应用哪些标准。 假设您有一个处理城市的程序:
protected Set<City> cities;
(...)
Field temperatureField = City.class.getDeclaredField("temperature");
Field numberOfInhabitantsField = City.class.getDeclaredField("numberOfInhabitants");
Field rainfallField = City.class.getDeclaredField("rainfall");
program.showCitiesSortBy(temperatureField, numberOfInhabitantsField, rainfallField);
(...)
public void showCitiesSortBy(Field... fields) {
List<City> sortedCities = new ArrayList<City>(cities);
Collections.sort(sortedCities, new City.CityMultiComparator(fields));
for (City city : sortedCities) {
System.out.println(city.toString());
}
}
您可能需要添加一个额外的精度层,以指定每个字段的排序应该是升序还是后代。我猜解决方案是将
field
对象替换为可以调用SortedField
的类的对象,该类包含一个field
对象,以及另一个表示升序或后代的字段这个问题的第二个答案是一个很好的例子。这有帮助吗:@sim,那么你为什么不花点时间去理解,而不是去寻找代码呢?@Moonbeam,我问题的文本显示我研究了收集和排序,我显示我已经阅读了Stackoverflow上的其他类似问题。你怎么会认为我我只是在寻找代码?下次,请不要无视惠顿定律。@Moonbeam,有时候你会看到代码来理解一个概念。当然像“我的树视图闪烁了一些可怕的东西!”试试这个“谢谢!”对任何人都没有帮助,但这就是为什么这是stac
public static class CityMultiComparator implements Comparator<City> {
protected List<Field> fields;
public CityMultiComparator(Field... orderedFields) {
fields = new ArrayList<Field>();
for (Field field : orderedFields) {
fields.add(field);
}
}
@Override
public int compare(City cityA, City cityB) {
Integer score = 0;
Boolean continueComparison = true;
Iterator itFields = fields.iterator();
while (itFields.hasNext() && continueComparison) {
Field field = itFields.next();
Integer currentScore = 0;
if (field.getName().equalsIgnoreCase("temperature")) {
currentScore = cityA.getTemperature().compareTo(cityB.getTemperature());
} else if (field.getName().equalsIgnoreCase("numberOfInhabitants")) {
currentScore = cityA.getNumberOfInhabitants().compareTo(cityB.getNumberOfInhabitants());
} else if (field.getName().equalsIgnoreCase("rainfall")) {
currentScore = cityA.getRainfall().compareTo(cityB.getRainfall());
}
if (currentScore != 0) {
continueComparison = false;
}
score = currentScore;
}
return score;
}
}