[英]Sorting by two fields of object. Java
I want to sort by date and name.我想按日期和名称排序。 For example I have date like this
例如我有这样的约会
2019 01 01 "CCCC"
2019 02 01 "Aaaa"
2019 03 01 "CCC"
2019 02 01 "BBBB"
2019 03 01 "Aaaa"
2019 01 01 "Aaaa"
I need to sort by month (and year) and alphabet, for example it must be like this:我需要按月(和年)和字母排序,例如它必须是这样的:
2019 01 01 "Aaaa"
2019 01 01 "CCCC"
2019 02 01 "Aaaa"
2019 02 01 "BBBB"
2019 03 01 "Aaaa"
2019 03 01 "CCC"
I have written code like this:我写过这样的代码:
Collections.sort(mainList, new Comparator<DocSet>() {
public int compare(DocSet o1, DocSet o2) {
SimpleDateFormat sdf = new SimpleDateFormat(Until.DATE_FORMAT);
Calendar c1 = null;
try {
String docSetDate1 = ((DocSet) o1).getDate();
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
c1 = Calendar.getInstance();
c1.setTime(sdf.parse(docSetDate1));
}catch (Exception e){}
Calendar c2 = null;
try {
String docSetDate2 = ((DocSet) o2).getDate();
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
c2 = Calendar.getInstance();
c2.setTime(sdf.parse(docSetDate2));
}catch (Exception e){}
int sComp = c1.compareTo(c2);
if (sComp != 0) {
return sComp;
}
String company_name1 = o1.getCompany_name();
String company_name2 = o2.getCompany_name();
return company_name1.compareTo(company_name2);
}
});
But it is sorting by date only, like this:但它仅按日期排序,如下所示:
2019 01 01 "CCCC"
2019 01 01 "Aaaa"
2019 02 01 "Aaaa"
2019 02 01 "BBBB"
2019 03 01 "CCC"
2019 03 01 "Aaaa"
UPDATE How can I by month (and year) and alphabet?更新我如何按月(和年)和字母表? My resulting data must be like this:
我得到的数据必须是这样的:
2019 01 01 "Aaaa"
2019 01 01 "CCCC"
2019 02 01 "Aaaa"
2019 02 01 "BBBB"
2019 03 01 "Aaaa"
2019 03 01 "CCC"
Three points:三点:
SimpleDateFormat
and Date
classes are poorly designed and long outdated, the former in particular notoriously troublesome. SimpleDateFormat
和Date
类的设计很差,而且已经过时了,前者尤其麻烦。LocalDate
or LocalDateTime
.LocalDate
或LocalDateTime
。Comparator.comparing()
and .thenComparing()
for much simpler and terser and first and foremost less error-prone code.Comparator.comparing()
和.thenComparing()
来获得更简单、更简洁、最重要的是更不容易出错的代码。 In code:在代码中:
List<DocSet> mainList = Arrays.asList(
new DocSet(LocalDate.of(2019, Month.JANUARY, 1), "CCCC"),
new DocSet(LocalDate.of(2019, Month.FEBRUARY, 1), "Aaaa"),
new DocSet(LocalDate.of(2019, Month.MARCH, 1), "CCC"),
new DocSet(LocalDate.of(2019, Month.FEBRUARY, 1), "BBBB"),
new DocSet(LocalDate.of(2019, Month.MARCH, 1), "Aaaa"),
new DocSet(LocalDate.of(2019, Month.JANUARY, 1), "Aaaa"));
Collections.sort(mainList,
Comparator.comparing(DocSet::getDate).thenComparing(DocSet::getCompanyName));
mainList.forEach(System.out::println);
The output from this snippet is:此代码段的输出是:
2019-01-01 Aaaa 2019-01-01 CCCC 2019-02-01 Aaaa 2019-02-01 BBBB 2019-03-01 Aaaa 2019-03-01 CCC
You notice that the objects have been sorted first by date, next by company name.您注意到对象首先按日期排序,然后按公司名称排序。
If you want case-insensitive sorting of company names, use如果要对公司名称进行不区分大小写的排序,请使用
Collections.sort(mainList,
Comparator.comparing(DocSet::getDate)
.thenComparing(DocSet::getCompanyName, String::compareToIgnoreCase));
Your code works as you say you want it to.您的代码按您说的那样工作。 The image that you linked to in a comment documents that your objects are sorted first by date and time (190101120010 before 190103120010), next by company name (AAAAAAAAAbdc1 before Abdc1).
您在评论中链接到的图像记录了您的对象首先按日期和时间排序(190101120010 在 190103120010 之前),其次是公司名称(在 Abdc1 之前的 AAAAAAAAAbdc1)。
For the sake of a complete example here is the DocSet
class that I have used in the above code:为了一个完整的例子,这里是我在上面的代码中使用的
DocSet
类:
public class DocSet {
LocalDate date;
String companyName;
public DocSet(LocalDate date, String companyName) {
this.date = date;
this.companyName = companyName;
}
public LocalDate getDate() {
return date;
}
public String getCompanyName() {
return companyName;
}
@Override
public String toString() {
return "" + date + ' ' + companyName;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.