[英]Custom comparison using Comparator
我有一个变量,可以采用三个可能的值(或状态): Available, Partial, Not Available
。
现在,我有这些状态的列表。 我的工作是将整个结果汇总为一个状态。 我的意思是,即使列表中的状态之一为“ Not Available
,整个状态也将变为“ Not Available
。
如果列表中的所有状态均为“ Available
,而其中一个状态为“ Partial
,则总体状态为“ Partial
。
目前,我正在使用一种非常幼稚的方法,在该方法中,我拥有与每种可能状态相对应的值,然后将它们逐一进行比较。
public class StringsInCusomOrder {
public static String overallStatus(ArrayList<String> statusList) throws Exception
{
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Available", 0);
map.put("Partial", 1);
map.put("Not Available", 2);
String overallstatus = "Available";
int value = 0;
for( String s : statusList)
{
if(map.get(s) > value)
{
overallstatus = s;
value = map.get(s);
}
}
return overallstatus;
}
public static void main(String[] args) throws Exception {
ArrayList<String> statusList = new ArrayList<String>();
statusList.add("Available");
statusList.add("Partial");
statusList.add("Not Available");
statusList.add("Partial");
System.out.println(overallStatus(statusList));
}
}
我想知道是否有更好的方法? 我可以使用比较器进行此自定义比较吗?
我建议对状态值使用Enum而不是String。
然后,您可以简单地使用Collections.min()
来获取EnumSet的最小值,如下所示:
public Enum Status {
NOT_AVAILABLE,
PARTIAL,
AVAILABLE
}
public Status overallStatus(EnumSet<Status> statusList) {
return Collections.min(statusList);
}
如果要使用contains
操作,则值得注意的是,对于List
,这是O(n)
,对于Set
,则只有O(1)
,因此一种更简洁的方法是:
public String getStatus(final Collection<String> in) {
final Set<String> set = new HashSet<>(in);
if (set.contains("Not Available")) {
return "Not Available";
}
if (set.contains("Partial")) {
return "Partial";
}
return "Available";
}
但是我更喜欢基于enum
的方法,因为这是通往if
s专制的快速之路。
public String listStatus(List<String> toCheck) {
if (toCheck.contains("Not available")) {
return "Not available";
} else if (toCheck.contains("Partial")) {
return "Partial";
} else {
return "Available";
}
}
试试这个
public static String overallStatus(ArrayList<String> statusList)
{
if(statusList.contains("Not Available"))
return "Not Available";
else if(statusList.contains("Partial"))
return "Not Available";
return "Available";
}
我将使用一个enum
类:
public enum Status {
AVAILABLE("Available"),
PARTIAL("Partial"),
NOT_AVAILABLE("Not Available");
private static final Map<String, Status> LOOKUP;
static {
LOOKUP = new HashMap<>();
for (final Status s : values()) {
LOOKUP.put(s.key, s);
}
}
public static Status lookup(final String status) {
final Status s = LOOKUP.get(status);
if (status == null) {
throw new IllegalArgumentException(status + " not a vaild status.");
}
return s;
}
public static Status getStatus(final Iterable<String> input) {
final SortedSet<Status> transformed = new TreeSet<>();
for (final String in : input) {
transformed.add(lookup(in));
}
return transformed.last();
}
//Alternative method not using a SortedSet and getting the max on the fly
public static Status getStatus(final Iterable<String> input) {
Status max = Status.AVAILABLE;
for (final String in : input) {
final Status curr = lookup(in);
if (curr.compareTo(max) > 0) {
max = curr;
}
}
return max;
}
private final String key;
private Status(String key) {
this.key = key;
}
}
enum
封装状态码。 有一些static
方法可以将您的String
状态转换为enum
的实例。
为了获得当前Status
将Iterable<String>
转换为SortedSet<Status>
。 默认情况下,枚举按声明顺序排序,因此只需完成对transformed.last()
的调用即可找到“最高”状态。
我认为这种方法更好地比较了String
因为它将Status
和相关方法封装到一个类中。
我建议您在代码中的其他位置使用Status
对象而不是String
,因为这样也可以增加类型安全性。
您可以使用更好的方法:
String currentStatus = statusList.get(0);
for( String s : statusList) {
if (s.equalsIgnoreCase("Partial"))
currentStatus = s;
else if (s.equalsIgnoreCase("NotAvailable");
return s;
}
return currentStatus;
这样,您仅一次扫描列表。 如果所有状态均可用,则最终状态为可用。 如果至少一个元素是Partial并且没有NotAvailable,则您的最终状态是Partial。 如果只有一个NotAvailable状态,则您的最终状态为NotAvailable。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.