当前位置: 首页 > 知识库问答 >
问题:

有没有办法把这个for循环改成使用Java流?

黄意智
2023-03-14
Set<String> unique = new HashSet<>();
List<String> duplicates = new ArrayList<>();

for (Animal cat: animals) {
    if (!unique.add(cat.getName())) {
        duplicates.add(cat.getName());
    }
}
return duplicates;

我想知道是否有办法简化这个?我是Java流的新手,我尝试使用Map,但我使用了传统的for循环

共有3个答案

郤令
2023-03-14

我不知道这是否可以被认为是一种简化,但这里有一种方法可以对流进行简化:

return animals.stream()
        .collect(Collectors.groupingBy(Animal::getName))
        .values()
        .stream()
        .flatMap(group -> group.stream().skip(1))
        .map(Animal::getName)
        .collect(Collectors.toList());
融焕
2023-03-14

是否要根据动物名称提取动物列表的重复字符串名称?尽管您的代码不涉及第一个找到的重复项,并返回重复项位于 n-1 计数中的 List,但这里是:

Set<String> set = new HashSet<>();
List<String> names = animals.stream()
                            .map(cat -> cat.getName())      // Names to collect and compare
                            .filter(name -> !set.add(name)) // Collect duplicates
                            .collect(Collectors.toList());  // To the List

此解决方案基于<code>for循环

这里有一个关于流的替代工作方式——API文档——但是有点复杂:

List<String> names = animals.stream()
    .collect(Collectors.groupingBy(
         Animal::getName, 
         Collectors.counting()))            // Collects to Map <name, count>
    .entrySet()                             // Gets the entries
    .stream()                               // Stream of the entries
    .filter(entry -> entry.getValue() > 1)  // Filters the duplicates
    .map(entry -> Collections.nCopies(      // Creates n-1 copies of the key as same as the
        entry.getValue().intValue() - 1,    //   OP's sample consumes the first duplication
        entry.getKey()))                    //   and includes the remainin ones
    .flatMap(List::stream)                  // Flattens the structure
    .collect(Collectors.toList());          // Results in the List

两种方式都来自输入:

List<Animal> animals = Arrays.asList(
    new Animal("A"), new Animal("A"), new Animal("A"), 
    new Animal("B"), new Animal("B"), new Animal("C"));

以下输出(无序):

[A, B, A]

商嘉木
2023-03-14

我想知道是否有办法简化这一点?我

流方式可能不是您的需求所需要的,您的代码实际上很简单。

流允许从输入(流)传递

a-

实际上你的代码不能依赖这样的逻辑,因为返回的< code >列表

List<String> duplicates =     
    animals.stream()
           .collect(Collectors.groupingBy(Animal::getName))
           .entrySet().stream()
           .filter(e -> e.getValue().size() > 1)
           .map(Entry::getKey)
           .collect(Collectors.toList());

您希望按出现的顺序返回每个重复出现的List
这意味着您不映射Stream

a-

因为如果结果中没有添加动物名称,就需要过滤掉元素...但是流并不是用来递增地填充结果的。所以你被困住了。

你可以写这个,但正如所说的,这确实不是一个简化,而且它仍然没有应用相同的逻辑,因为dup名称的顺序与代码中的顺序不同:

List<String> duplicates = 
          animals.stream()
                 .collect(Collectors.groupingBy(Animal::getName, LinkedHashMap::new, Collectors.toList()))
                 .values().stream()
                 .flatMap(l-> l.stream().skip(1)) 
                 .map(Animal::getName)
                 .collect(Collectors.toList());

 类似资料:
  • 问题内容: 有没有办法使用泛型说“此方法返回”? 当然,我想在子类中重写此方法,因此声明应与一起使用。 这是一个例子: 根本不起作用:我收到“类型不匹配:无法从Base转换为T”。如果我强制使用强制转换,则覆盖将失败。 问题答案: 不,无法表达这一点。只需声明该方法即可返回类的类型。Java具有协变返回类型,因此无论如何您都可以重写方法以返回更特定的类型。 如果您想为此添加一些标记,则可以随时引入

  • 问题内容: Java的for-each循环中是否有办法 找出循环已被处理的频率? 除了使用旧的和众所周知的-环,是构建 在for-each循环中提供此类计数器的唯一方法是? 问题答案: 不可以,但是你可以提供自己的柜台。 这样做的原因是,for-each循环在内部不具有一个计数器; 它基于接口,即它使用一个Iterator循环遍历“集合”的过程-可能根本不是一个集合,并且实际上可能根本不是基于索引

  • GeoFire与实时数据库紧密耦合,而地理查询是许多希望迁移到FireStore的应用程序的常见功能依赖项。有没有办法在Firestore环境中复制位置的散列/检索?

  • 我想使用以下循环创建一个新列。表中只有“open”和“start”列。我想创建一个新列“startopen”,如果“start”等于1,那么“startopen”等于“open”。否则,“startopen”等于此新创建列上方行中的任何“startopen”。目前,我能够通过以下方式实现这一点: 这有效,但对于大型数据集来说非常慢。是否有任何内置函数可以更快地完成此操作?

  • 问题内容: 我有两个长度相同的列表对象,并且要渲染互补数据,有没有一种方法可以同时渲染两个列表对象。 或类似的东西? 问题答案: 如果两个列表的长度相同,则可以在视图中作为模板上下文返回,从而生成一个二值元组列表。 例: 然后,您可以在模板中编写: 另外,在此处查看有关模板标记的Django文档。它提到了使用它的所有可能性,包括漂亮的示例。

  • 我使用的界面看起来大致如下: 并且我目前正在使用一个匿名类来实现接口,但我并不关心这两种方法中的一种。大致如下: 现在,我已经在Java8中尽可能地使用新的lambda表达式,我想在这种情况下使用增加的简单性。毕竟,我只是在实现其中的一个方法,但由于接口中有两个方法,所以我不能在一个lambda表达式中使用它。