簡體   English   中英

使用比較器進行自定義比較

[英]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的實例。

為了獲得當前StatusIterable<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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM