繁体   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