转换数组并将其复制到List中

时间:2016-02-03 17:25:27

标签: java arraylist enums java-8

要明确我没有任何问题,并且真的不需要帮助,但无论如何我想问:

我们说我们有一个String数组

String[] sarr = new String[]{"POTATO", "TOMATO"};

我们有一个枚举

public enum Food{POTATO, TOMATO, PIZZA}

如果我想检查sarrFood中是否存在所有字符串,请执行以下操作:

ArrayList<String> foodstrings = new ArrayList<>();
Arrays.asList(Food.values()).forEach((in) -> foodstrings.add(in.toString()));
if (!foodstrings.containsAll(Arrays.asList(sarr))) doStuff();

有没有办法在更少的代码行中执行此操作?或者只是一种更优雅的方式?

3 个答案:

答案 0 :(得分:6)

您想确定数组中的所有元素是否都包含在食物名称列表中。

一种可能的解决方案是将食物名称转换为Set(具有O(1)contains);那么,我们需要确定数组中的所有元素是否都包含在这个集合中:

public static void main(String[] args) {
    String[] sarr = new String[]{"POTATO", "TOMATO"};
    Set<String> set = Arrays.stream(Food.values()).map(Enum::name).collect(Collectors.toSet());
    boolean result = Arrays.stream(sarr).allMatch(set::contains);
}

在您当前的解决方案中,您使用forEach改变外部变量,这是一种不好的做法。

答案 1 :(得分:4)

我相信前两行的更好版本是:

app:layout_behavior

使用Set<String> foodstrings = Arrays.stream(Food.values()).map(Enum::name).collect(Collectors.toSet()); 代替Set可以提高List的效果,代码完全流式传输,而不是使用containsAll和外部收集器。

forEach仍然很好,虽然您可以将它们全部合并到一个语句中(格式化为可读性):

if

答案 2 :(得分:0)

if (Stream.of(sarr).allMatch(s -> Stream.of(Food.values()).anyMatch(t -> s.equals(t.name()))))
{ 
    // all match
}
  1. sarr创建一个流(可以是适用于Java 1.8中引入的Collection API的任何Stream个对象。
  2. 我们要求值allMatch,如果true(即返回true / false的函数),则只返回Predicate
  3. 对于Predicate期望的allMatch,我们提供了一个lambda,它通过流迭代第二组对象,并调用anyMatch:一个简单的Predicate如果任何成员对象满足提供的条件(再次,布尔函数),则返回true。
  4. 我们为anyMatch提供了另一个lambda,它通过equals实现来比较2个集合的成员。
  5. 此解决方案在语义上等同于不变

    A \subset B

    在我们的案例中是

    sarr \subset Food.values()

    和以下Java&lt; 1.8如下所示的代码,带有短路模拟规范(减去流开销):

    // assume success, since if both sets are empty the invariant holds
    boolean subset = true; 
    
    for (String a : sarr)
    {
      if (null == a) continue;
      boolean contained = false;
    
      for (Food b : Food.values()) 
        if (b.name().equals(a)) { contained = true; break; }
    
      if (!contained) { subset = false; break; }
    }
    
    if (subset)
    {
       // all match
    }
    

    当然,您可以替换不同的集合类型和条件,以及使用parallelStream()来更好地利用可用的硬件。