使用流检查Java中列表是否仅具有特定元素排列

时间:2018-07-26 03:10:32

标签: java java-stream

我正在尝试提出使用流解决此问题的解决方案,并且我查找是否有人遇到了此问题但找不到此问题。 因此,我有一个包含三个元素的列表,将其命名为list1,另一个列表称为list2,它可以具有不同的元素,并且还可以包含list1中的重复项。

我想实现的目标:-

  1. 检查list2是否具有list1中没有的任何元素。
  2. 检查一次list2是否只有一次来自list1的2个项目。

对于2-我可以使用set,将list2转换为set,然后查看list1是否包含所有set。

但是我想知道我是否可以在这里使用流!

例如

list1(1,2,3)和list2(1,1,2,2)-返回true

list1(1,2,3)和list2(1,1,3,3)-返回true

list1(1,2,3)和list2(1,1,2,2,4)-返回false

我希望这不太清楚

3 个答案:

答案 0 :(得分:2)

  public static <T> boolean func(List<T> list1, List<T> list2) {
    return list2.stream()
        .distinct()
        .map(list1::contains)
        .reduce(0,
            (result, current) -> result < 0 ? -1 : (current ? result + 1 : -1),
            (a, b) -> a < 0 || b < 0 ? -1 : a + b) == 2;
  }

但是建议您不要将流用于如此复杂的逻辑。

答案 1 :(得分:1)

流可能不是解决此问题的最有效方法。但是,这是另一种方法,一旦发现list1中包含的第三个元素或不包含的第一个元素,便具有短循环的优势:

public static <T> boolean func(List<T> list1, List<T> list2)
{
    AtomicLong count = new AtomicLong(0);
    return list2.stream()
                .distinct()
                .allMatch(element -> list1.contains(element) &&
                                     count.incrementAndGet() < 3)
           && count.get() == 2;
}

尽管如此,我们还是要“作弊”:为了不经历完整的流程,我们必须借助计数器来限制元素。

检查&& count.get() == 2确保list1中包含2个元素。如果0或1元素也可以接受,请删除该检查。

答案 2 :(得分:0)

怎么样:

return Optional.of(list2)
        .filter(list -> list.stream().allMatch(list1::contains))
        .map(list -> list.stream().distinct().map(list1::contains))
        .map(stream -> stream.mapToInt(x -> x ? 1 : 0))
        .map(IntStream::sum)
        .filter(sum -> sum == 2)
        .isPresent();

不幸的是,您实际上执行了两次相同的流操作。或者,为避免这种情况,请收集流并重新转换:

List<Boolean> containedInFirst = list2.stream()
        .distinct()
        .map(list1::contains)
        .collect(Collectors.toList());
return Optional.of(containedInFirst)
        .filter(list -> list.stream().allMatch(x -> x))
        .map(list -> list.stream().mapToInt(x -> x ? 1 :0))
        .map(IntStream::sum)
        .map(sum -> sum == 2)
        .filter(sum -> sum == 2)
        .isPresent();

您实际上是在创建两个带有可选轨道的轨道:一个与您的需求匹配的轨道,另一个与您的需求不匹配。每当您发现不匹配的内容时,就会使用过滤器将其丢弃。 isPresent仍在管道中的所有内容都符合您的条件。