使用Comparator进行自定义比较

时间:2013-12-13 08:19:16

标签: java

我有一个变量可以采用三个可能的值(或状态):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));
}
}

我想知道是否有更好的方法来做到这一点?我可以使用比较器来进行这种自定义比较吗?

6 个答案:

答案 0 :(得分:2)

我建议使用Enum作为状态值而不是String 然后,您可以简单地使用Collections.min()来获取EnumSet的最低值,如下所示:

public Enum Status {
  NOT_AVAILABLE,
  PARTIAL,
  AVAILABLE
}

public Status overallStatus(EnumSet<Status> statusList) {
  return Collections.min(statusList);
}

答案 1 :(得分:2)

如果您想使用contains操作,那么值得注意的是O(n)ListO(1)只有Set更清洁的方法是:

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的暴政的快速道路。

答案 2 :(得分:1)

public String listStatus(List<String> toCheck) {

    if (toCheck.contains("Not available")) {
        return "Not available";
    } else if (toCheck.contains("Partial")) {
        return "Partial";
    } else {
        return "Available";
    }
}

答案 3 :(得分:1)

试试这个

   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";
    }

答案 4 :(得分:1)

我会使用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,因为这样会增加类型安全性。

答案 5 :(得分:0)

您可以使用更好的方法:

String currentStatus = statusList.get(0);
for( String s : statusList) {
    if (s.equalsIgnoreCase("Partial"))
        currentStatus = s;
    else if (s.equalsIgnoreCase("NotAvailable");
        return s;
}
return currentStatus;

这样您只需一次扫描列表。 如果所有状态都可用,则最终状态为Available。 如果元素中至少有一个是Partial且没有NotAvailable,则最终状态为Partial。 如果只有一个NotAvailable状态,则最终状态为NotAvailable。