我有一个名为漏洞的bean。它有一个列“严重性”。
private String severity;
严重性可以包含字符串值High,Medium和Low。现在每当根据严重性列对该bean进行排序时,它按字母顺序排列即高,低和中等。但我希望排序在下降时发生高,中,低,在升序时发生低,中,高。 我看到比较器进行这种自定义排序,但它需要涵盖很多案例。不是他们的任何其他方式吗?
答案 0 :(得分:1)
在compareTo
上定义了隐式enum
运算符takes their declaration order to mean "smaller than"。 无需其他代码。
enum Severity { Low, Medium, High }
Low.compareTo(High); // returns -1
Medium.compareTo(Low); // returns 1
但请注意,枚举常量的名称将是toString()
打印的名称(因此,如果您直接回显枚举,则对用户可见) - 如果您想使用不同的内部和外部名称,可能要坚持代码约定(比如all-caps-constants),然后你需要添加一个枚举构造函数并覆盖枚举的toString
方法来使用传入的构造函数属性。
如果您无法使用枚举,则无法更改您的bean
然后为它构建一个Comparator:
public class SeverityComparator implements Comparator<String> {
private int direction;
public SeverityComparator(boolean reverse) {
this.direction = reverse ? -1 : 1;
}
private int severity(String s) {
if (s.equals("Low")) { // you really should have constants for the values...
return 0;
} else if (s.equals("Medium")) {
return 1;
} else if (s.equals("High")) {
return 2;
} else {
throw new IllegalArgumentException("Not a severity: " + s);
}
}
@Override
public int compareTo(String other) {
return direction * (severity(this) - severity(other));
}
}
用作
Collections.sort(listOfSeverities, new SeverityComparator(false)); // ascending
Collections.sort(listOfSeverities, new SeverityComparator(true)); // descending
答案 1 :(得分:0)
你可以(并且应该)使用枚举 - 不是字符串也不是int:
enum Severity {
LOW, MEDIUM, HIGH;
}
<强>用法:强>
List<Severity> lst = new ArrayList<Severity>();
lst.add(Severity.MEDIUM);
lst.add(Severity.LOW);
lst.add(Severity.HIGH);
for (Severity s : lst)
System.out.println("s = " + s);
Collections.sort(lst);
System.out.println();
for (Severity s : lst)
System.out.println("s = " + s);
<强>输出:强>
s = MEDIUM
s = LOW
s = HIGH
s = LOW
s = MEDIUM
s = HIGH
修改强>
由于OP说他无法修改字符串的使用,我们可以将字符串映射到可比较的值:
static Map<String, Integer> severities = new HashMap<String, Integer>();
static {
severities.put("LOW",1);
severities.put("MEDIUM",2);
severities.put("HIGH",3);
}
public static void main(String[] args) {
List<String> lst = new ArrayList<String>();
lst.add("MEDIUM");
lst.add("LOW");
lst.add("HIGH");
for (String s : lst)
System.out.println("s = " + s);
Collections.sort(lst, new Comparator<String>() {
public int compare(String a1, String a2) {
Integer v1 = severities.get(a1);
Integer v2 = severities.get(a2);
return v1.compareTo(v2);
}
});
System.out.println();
for (String s : lst)
System.out.println("s = " + s);
}
如果您想按降序排列项目,可以排序然后反转:
Collections.sort(lst);
Collections.reverse(lst);
答案 2 :(得分:0)
@alfasin答案是正确的,但我建议使用番石榴的订购:
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
import javax.annotation.Nullable;
import java.util.List;
public class SeveritySortTest {
private static final List<Severity> SEVERITY_LIST = ImmutableList.copyOf(Severity.values());
public static void main(String[] args) {
Ordering<Severity> severityOrdering = Ordering.natural().onResultOf(new Function<Severity, Integer>() {
@Nullable
@Override
public Integer apply(@Nullable Severity input) {
return input.getSeverity();
}
});
List<Severity> sortedAscending = severityOrdering.sortedCopy(SEVERITY_LIST);
List<Severity> sortedDescending = severityOrdering.reverse().sortedCopy(SEVERITY_LIST);
}
enum Severity {
LOW(1), MEDIUM(2), HIGH(3);
private int severity;
Severity(int s) {
severity = s;
}
int getSeverity() {
return severity;
}
}
}
答案 3 :(得分:0)
工作解决方案:
Collections.sort(推荐,新的Comparator(){
private int priority(String s) {
if (s.equalsIgnoreCase("Low")) {
return 1;
} else if (s.equalsIgnoreCase("Medium")) {
return 2;
} else if (s.equalsIgnoreCase("High")) {
return 3;
} else {
return 0;
}
}
@Override
public int compare(Recommendation o1, Recommendation o2) {
return -1 * (priority(o1.getPriority()) - priority(o2.getPriority()));
}
});
答案 4 :(得分:0)
如果您希望数据库通过JPA / Hibernate进行此操作,则可以基于简单的case语句创建一个排序表达式,假设您的实体称为Case:
Expression exp = criteriaBuilder.selectCase(root.get(Case_.priority)).when("High", 1).when("Medium", 2).otherwise(3);
queryBuilder.orderBy(orderDir.isAscending() ? criteriaBuilder.asc(exp) : criteriaBuilder.desc(exp));
在order by子句中使用case语句不利于性能,但可以解决问题。与Oracle配合使用。