간단한 수업이 있습니다
public class ActiveAlarm {
public long timeStarted;
public long timeEnded;
private String name = "";
private String description = "";
private String event;
private boolean live = false;
}
그리고 List<ActiveAlarm>
죄수. 을 기준으로 오름차순으로 정렬 timeStarted
한 다음 timeEnded
? 아무도 도와 줄 수 있습니까? 나는 일반적인 알고리즘과 과부하 연산자 <를 사용하여 C ++에서 알고 있지만 Java를 처음 사용합니다.
답변
어느 만든다 ActiveAlarm
구현 Comparable<ActiveAlarm>
하거나 구현하는 Comparator<ActiveAlarm>
별도의 클래스에서. 그런 다음 전화 :
Collections.sort(list);
또는
Collections.sort(list, comparator);
일반적으로, 구현하는 좋은 아이디어이다 Comparable<T>
, 그렇지 않으면 … 하나의 “자연”정렬 순서가 있다면 (당신이 경우 일어날 특정 순서로 정렬 할 것이 아니라, 동등하게 쉽게 다른 일을 할 수 있습니다) 그것을 구현하는 것이 좋습니다 Comparator<T>
. 이 특정 상황은 솔직히 말해서 어느 쪽이든 갈 수 있지만 더 유연한 옵션을 고수 할 것 입니다Comparator<T>
.
편집 : 샘플 구현 :
public class AlarmByTimesComparer implements Comparator<ActiveAlarm> {
@Override
public int compare(ActiveAlarm x, ActiveAlarm y) {
// TODO: Handle null x or y values
int startComparison = compare(x.timeStarted, y.timeStarted);
return startComparison != 0 ? startComparison
: compare(x.timeEnded, y.timeEnded);
}
// I don't know why this isn't in Long...
private static int compare(long a, long b) {
return a < b ? -1
: a > b ? 1
: 0;
}
}
답변
사용 Comparator
예를 들어 :
class Score {
private String name;
private List<Integer> scores;
// +accessor methods
}
Collections.sort(scores, new Comparator<Score>() {
public int compare(Score o1, Score o2) {
// compare two instance of `Score` and return `int` as result.
return o2.getScores().get(0).compareTo(o1.getScores().get(0));
}
});
Java 8부터는 람다 식을 사용하여 Comparator 인스턴스를 나타낼 수 있습니다.
Collections.sort(scores, (s1, s2) -> { /* compute and return int */ });
답변
자바 8 이상 답변 (람다 식 사용)
Java 8에서는 Lambda 표현식이 도입되어 더욱 쉬워졌습니다! 모든 스캐 폴딩으로 Comparator () 객체를 만드는 대신 다음과 같이 단순화 할 수 있습니다. (객체를 예제로 사용)
Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.timeStarted-a2.timeStarted);
또는 더 짧게 :
Collections.sort(list, Comparator.comparingInt(ActiveAlarm ::getterMethod));
그 진술은 다음과 같습니다.
Collections.sort(list, new Comparator<ActiveAlarm>() {
@Override
public int compare(ActiveAlarm a1, ActiveAlarm a2) {
return a1.timeStarted - a2.timeStarted;
}
});
Lambda 표현식은 코드의 관련 부분 (메소드 서명 및 반환되는 항목) 만 입력하면된다고 생각하십시오.
질문의 또 다른 부분은 여러 필드와 비교하는 방법이었습니다. Lambda 표현식으로이를 수행하려면이 .thenComparing()
함수를 사용 하여 두 비교를 하나로 결합 할 수 있습니다 .
Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.timeStarted-a2.timeStarted
.thenComparing ((ActiveAlarm a1, ActiveAlarm a2) -> a1.timeEnded-a2.timeEnded)
);
위의 코드는 목록을 먼저 정렬 timeStarted
한 다음 timeEnded
(같은 레코드에 대해) 정렬합니다 timeStarted
.
마지막 참고 사항 : ‘long’또는 ‘int’프리미티브를 쉽게 비교할 수 있습니다. 서로를 빼면됩니다. 객체 ( ‘Long’또는 ‘String’)를 비교하는 경우 기본 제공 비교를 사용하는 것이 좋습니다. 예:
Collections.sort(list, (ActiveAlarm a1, ActiveAlarm a2) -> a1.name.compareTo(a2.name) );
편집 : .thenComparing()
기능을 알려주는 Lukas Eder에게 감사드립니다 .
답변
다음 두 가지 방법 중 하나로 목록을 정렬 할 수 있습니다.
1. 비교기 사용 : 여러 장소에서 정렬 논리를 사용해야하는 경우 단일 장소에서 정렬 논리를 사용하려면 다음과 같이 익명 내부 클래스를 작성하거나 비교기를 추출하여 여러 위치에서 사용할 수 있습니다.
Collections.sort(arrayList, new Comparator<ActiveAlarm>() {
public int compare(ActiveAlarm o1, ActiveAlarm o2) {
//Sorts by 'TimeStarted' property
return o1.getTimeStarted()<o2.getTimeStarted()?-1:o1.getTimeStarted()>o2.getTimeStarted()?1:doSecodaryOrderSort(o1,o2);
}
//If 'TimeStarted' property is equal sorts by 'TimeEnded' property
public int doSecodaryOrderSort(ActiveAlarm o1,ActiveAlarm o2) {
return o1.getTimeEnded()<o2.getTimeEnded()?-1:o1.getTimeEnded()>o2.getTimeEnded()?1:0;
}
});
‘long’대신 ‘Long’을 사용할 수 있다면 속성을 null 검사 할 수 있습니다.
2. Comparable (natural ordering) 사용 : 정렬 알고리즘이 항상 하나의 속성을 고수하는 경우 : ‘Comparable’을 구현하는 클래스를 작성하고 아래 정의 된대로 ‘compareTo’메소드를 재정의하십시오.
class ActiveAlarm implements Comparable<ActiveAlarm>{
public long timeStarted;
public long timeEnded;
private String name = "";
private String description = "";
private String event;
private boolean live = false;
public ActiveAlarm(long timeStarted,long timeEnded) {
this.timeStarted=timeStarted;
this.timeEnded=timeEnded;
}
public long getTimeStarted() {
return timeStarted;
}
public long getTimeEnded() {
return timeEnded;
}
public int compareTo(ActiveAlarm o) {
return timeStarted<o.getTimeStarted()?-1:timeStarted>o.getTimeStarted()?1:doSecodaryOrderSort(o);
}
public int doSecodaryOrderSort(ActiveAlarm o) {
return timeEnded<o.getTimeEnded()?-1:timeEnded>o.getTimeEnded()?1:0;
}
}
자연 순서에 따라 정렬하는 정렬 방법 호출
Collections.sort(list);
답변
java8 +에서는 다음과 같이 한 줄로 작성할 수 있습니다.
collectionObjec.sort(comparator_lamda)
또는 comparator.comparing(CollectionType::getterOfProperty)
암호:
ListOfActiveAlarmObj.sort((a,b->a.getTimeStarted().compareTo(b.getTimeStarted())))
또는
ListOfActiveAlarmObj.sort(Comparator.comparing(ActiveAlarm::getTimeStarted))
답변
public class ActiveAlarm implements Comparable<ActiveAlarm> {
public long timeStarted;
public long timeEnded;
private String name = "";
private String description = "";
private String event;
private boolean live = false;
public int compareTo(ActiveAlarm a) {
if ( this.timeStarted > a.timeStarted )
return 1;
else if ( this.timeStarted < a.timeStarted )
return -1;
else {
if ( this.timeEnded > a.timeEnded )
return 1;
else
return -1;
}
}
그것은 당신에게 대략적인 아이디어를 줄 것입니다. 완료되면 Collections.sort()
목록에서 전화 를 걸 수 있습니다 .
답변
Java8부터는 Comparator
및Lambda expressions
예를 들어 :
class Student{
private String name;
private List<Score> scores;
// +accessor methods
}
class Score {
private int grade;
// +accessor methods
}
Collections.sort(student.getScores(), Comparator.comparing(Score::getGrade);