[英]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.