我必须通过Birthdate对人物对象的集合进行排序,因此我创建了以下pojo。
public class Person implements Comparable<Person> {
private long id;
private String name;
private Date birthDate;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
@Override
public int compareTo(Person person) {
if (getBirthDate() == null || person.getBirthDate() == null)
return 0;
return getBirthDate().compareTo(person.getBirthDate());
}
}
这可以排序出生日期,但我的额外要求是按出生日期最接近今天的升序排序。例如,如果今天是10月11日,那么生日将作为一个例子进行分类。
10月20日 11月5日 1月3日......
我现在拥有它的方式,因为这一年是可比的日期从最古老的一年到最近一年的一部分。
如何在没有这一年的情况下对这些生日进行排序?
答案 0 :(得分:4)
这可以用来分拣出生日期,但需要额外的 我要求的是按出生日期最接近的方式对它们进行排序 今天上升。因此,例如,如果今天是10月11日,那么 生日将作为一个例子进行分类
如果我理解你的话,在排序的时候,你不考虑年份,例如,1975年或是?在我看来,你是在生日后记住功能。但是,如果您要根据month and day
进行排序,那么以下comparedTo()
功能可以让您根据不同年份的月份和日期进行比较:
class Person implements Comparable<Person>
{
Date birthDay;
static SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy");
public Person(String birthDay) throws ParseException
{
this.birthDay = formatter.parse(birthDay);
}
@Override
public int compareTo(Person o) {
Calendar cal1 = Calendar.getInstance();
cal1.setTime(this.birthDay);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(o.birthDay);
int month1 = cal1.get(Calendar.MONTH);
int month2 = cal2.get(Calendar.MONTH);
if(month1 < month2)
return -1;
else if(month1 == month2)
return cal1.get(Calendar.DAY_OF_MONTH) - cal2.get(Calendar.DAY_OF_MONTH);
else return 1;
}
}
尝试使用以下代码测试:
List<Person>persons = new ArrayList<>();
persons.add(new Person("MAR 2, 2001"));
persons.add(new Person("JAN 7, 1972"));
persons.add(new Person("JAN 2, 1976"));
persons.add(new Person("MAR 4, 1985"));
Collections.sort(persons);
for(Person p : persons)
System.out.println(p.formatter.format(p.birthDay));
//Person.formatter is SimpleDateFormat with format "MMM dd, yyyy"
// in person class, i declared it as static
<强>输出强>:
Jan 02, 1976
Jan 07, 1972
Mar 02, 2001
Mar 04, 1985
根据角色对列表进行排序,例如,OCT 11
我认为在排序后你可以围绕列表,认为它是循环的。例如,假设排序列表:
JAN 20, FEB 5, SEP 18, OCT 9, OCT 20, NOV 23
如果我们的支点OCT 11
选择立即更大(大于枢轴的最小日期)日期,则为OCT 20
。您只需使用for loop
即可找到它。现在,我们只需要围绕它认为它是循环的:
OCT 20, NOV 23
- &gt; JAN 20, FEB 5, SEP 18, OCT 9
正式 ,根据月份和日期找到我们的数据透视表中即刻较大日期i
的索引comparing
(尝试使用compareTo示例),然后创建一个新列表,插入元素从索引i
开始到n-1
,然后0
到i-1
,这里n
的大小是出生日期清单。
我希望有所帮助。
答案 1 :(得分:1)
写一个Comparator
您可以为人员指定一个比较器,其中包括年份,另一个比较器将其排除。
您需要通过调用以下方式对列表进行排序:
Collections.sort(list, new BirthdayWithoutYearComparatr());
答案 2 :(得分:1)
你有一系列复杂的问题。
首先,我个人不会制作Person
类Comparable
,主要问题(我看到这个)是,它并不是真正比较Person
对象,而是只是其中一个属性。这会阻止您进行可能无法满足您所有要求的比较。
相反,我会建立一系列Comparator
来完成非常具体的工作,例如,比较Person
的出生日期。
下一个问题是类似的API不支持不匹配的参数,好吧,确实如此,但它很麻烦......
我们需要的是一些方法,我们可以将对象(或更具体地说,对象的属性)与其他值进行比较。
现在,因为核心API是基于比较相似的值,我们需要提供自己的实现来支持我们的需求。
因此,下面是一个快速排序实现,允许您提供List
个对象ISortMatcher
和要与之比较的值(这是所有值的基值)列表将与之比较)
import java.util.Collections;
import java.util.List;
public class QuickSort {
public static <O, M> void sort(List<O> values, M value, ISortMatcher<O, M> matcher) {
sort(values, value, matcher, 0, values.size() - 1);
}
protected static <O, M> void sort(List<O> values, M value, ISortMatcher<O, M> matcher, int low, int high) {
int i = low, j = high;
// Get the pivot element from the middle of the list
int pivot = matcher.compare(values.get(low + (high - low) / 2), value);
// Divide into two lists
while (i <= j) {
// If the current value from the left list is smaller then the pivot
// element then get the next element from the left list
while (matcher.compare(values.get(i), value) < pivot) {
i++;
}
// If the current value from the right list is larger then the pivot
// element then get the next element from the right list
while (matcher.compare(values.get(j), value) > pivot) {
j--;
}
// If we have found a values in the left list which is larger then
// the pivot element and if we have found a value in the right list
// which is smaller then the pivot element then we exchange the
// values.
// As we are done we can increase i and j
if (i <= j) {
Collections.swap(values, i, j);
i++;
j--;
}
}
// Recursion
if (low < j) {
sort(values, value, matcher, low, j);
}
if (i < high) {
sort(values, value, matcher, i, high);
}
}
public static interface ISortMatcher<O, M> {
public int compare(O o, M m);
}
}
好的,这是排序的一个非常具体的要求,有点像二进制搜索,但它会...
这允许我们做的是定义我们想要匹配的基值,执行比较的算法和要排序的值列表。它的工作原理与核心API类似,返回的值小于,等于或大于0,表示结果的权重。
现在,我们可以开始比较......
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
public class SortDates {
public static final SimpleDateFormat SDF = new SimpleDateFormat("dd/MM/yyyy");
public static void main(String[] args) {
new SortDates();
}
public SortDates() {
List<Person> people = new ArrayList<Person>(5);
for (int index = 0; index < 10; index++) {
Date date = getDate(
(int)(Math.random() * 30) + 1,
(int)(Math.random() * 12),
(int)(Math.random() * 113) + 1900);
people.add(new Person(date));
}
Collections.sort(people, new DateOfBirthComparator());
System.out.println("By date of birth");
for (Person p : people) {
System.out.println(p);
}
Collections.shuffle(people);
System.out.println("");
System.out.println("Shuffled");
for (Person p : people) {
System.out.println(p);
}
QuickSort.ISortMatcher matcher = new QuickSort.ISortMatcher<Person, Date>() {
@Override
public int compare(Person o, Date m) {
Calendar with = Calendar.getInstance();
with.setTime(m);
Calendar to = Calendar.getInstance();
to.setTime(o.getBirthDate());
to.set(Calendar.YEAR, with.get(Calendar.YEAR));
int withDOY = with.get(Calendar.DAY_OF_YEAR);
int toDOY = to.get(Calendar.DAY_OF_YEAR);
int result = 0;
if (withDOY < toDOY) {
result = toDOY - withDOY;
} else if (withDOY > toDOY) {
result = withDOY - toDOY;
}
return result;
}
};
QuickSort.sort(people, new Date(), matcher);
System.out.println("");
System.out.println("To today (" + SDF.format(new Date()) + ")");
for (Person p : people) {
System.out.println(p);
}
}
public Date getDate(int day, int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE, day);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.YEAR, year);
return cal.getTime();
}
public class Person {
private Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
@Override
public String toString() {
return SDF.format(birthDate);
}
public Date getBirthDate() {
return birthDate;
}
}
public class DateOfBirthComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.getBirthDate().compareTo(o2.getBirthDate());
}
}
}
示例的核心是QuickSort
Matcher
。这决定了在给定值和我们想要用作比较基础的值之间应用的权重。
QuickSort.ISortMatcher matcher = new QuickSort.ISortMatcher<Person, Date>() {
@Override
public int compare(Person o, Date m) {
Calendar with = Calendar.getInstance();
with.setTime(m);
Calendar to = Calendar.getInstance();
to.setTime(o.getBirthDate());
to.set(Calendar.YEAR, with.get(Calendar.YEAR));
int withDOY = with.get(Calendar.DAY_OF_YEAR);
int toDOY = to.get(Calendar.DAY_OF_YEAR);
int result = 0;
if (withDOY < toDOY) {
result = toDOY - withDOY;
} else if (withDOY > toDOY) {
result = withDOY - toDOY;
}
return result;
}
};
现在,我已按照字面意思对您提出要求,这将根据与给定Date
的距离对值进行排序,因此您可能会在指定日期之后的指定日期之前显示日期。 ..
例如,
By date of birth
05/10/1905
01/10/1906
13/03/1921
11/04/1942
07/12/1944
27/04/1953
05/07/1988
15/12/1988
19/03/1995
12/07/2001
Shuffled
13/03/1921
01/10/1906
05/07/1988
12/07/2001
11/04/1942
27/04/1953
19/03/1995
15/12/1988
07/12/1944
05/10/1905
To today (12/10/2013)
05/10/1905
01/10/1906
07/12/1944
15/12/1988
12/07/2001
05/07/1988
27/04/1953
11/04/1942
19/03/1995
13/03/1921
您可以看到05/10
出现在07/12
之前,因为它距离目标日期更近......