【问题标题】:Java 8 how to simplify for loop with lambda expressionsJava 8 如何使用 lambda 表达式简化 for 循环
【发布时间】:2020-11-23 11:43:54
【问题描述】:

我的代码中有这个方法,需要通过使用 java 8 表达式来简化和减少行。 Lambda 可以用于此,但如果没有列表作为输入,它似乎是不可能的。

  public ResourceUsage[] filterResourceUsages(ResourceUsage[] resourceUsages, int role, int includeResourceType)
    throws SpiderException
  {
    ArrayList<ResourceUsage> filteredResourceUsages = new ArrayList<>();

    String[] ids = new String[resourceUsages.length];
    for (int i = 0; i < resourceUsages.length; i++)
    {
      ids[i] = resourceUsages[i].resource;
    }

    ResourceData[] resourceData = resourceToolkitAdapter.getData(ids);

    for (int i = 0; i < resourceData.length; i++)
    {
      if (resourceUsages[i].role == role && resourceData[i].basic.type == includeResourceType)
      {
        filteredResourceUsages.add(resourceUsages[i]);
      }
    }
    return filteredResourceUsages.toArray(new ResourceUsage[filteredResourceUsages.size()]);
  }

我尝试过使用resourceUsages.forEach(resourceUsages.resource-&gt; do something);,但没有列表作为输入似乎是不可能的。

有什么办法可以简化这段代码?

【问题讨论】:

  • "没有列表作为输入似乎不可能" ... Arrays.stream(myArray)
  • 最终列表 ids = resourceUsages.stream().map(e -> e.resource).collect(toList());

标签: java for-loop lambda foreach java-8


【解决方案1】:

这里是原始数组和批处理解决方案:

public ResourceUsage[] filterResourceUsages(ResourceUsage[] resourceUsages, int role, int includeResourceType)
        throws SpiderException {

    String[] ids = Stream.of(resourceUsages)
            .map(ResourceUsage::getResource)
            .toArray(String[]::new);
    Map<String, ResourceData> resourceDataMap = Stream.of(resourceToolkitAdapter.getData(ids))
            .collect(Collectors.toMap(ResourceData::id, Function.identity()));
    return Stream.of(resourceUsages)
            .filter(usage -> usage.role == usage)
            .filter(resourceDataMap::containsKey)
            .filter(usage -> resourceDataMap.get(usage.resource).basic.type == includeResourceType)
            .toArray(ResourceUsage[]::new);
}

【讨论】:

    【解决方案2】:

    与Matthew的回答相反,我认为resourceToolkitAdapter.getData()应该用一批id来调用。

    public ResourceUsage[] filterResourceUsages(ResourceUsage[] resourceUsages, int role, int includeResourceType)
      throws SpiderException
    {
      ResourceData[] resourceData = resourceToolkitAdapter.getData(
        Arrays.stream(resourceUsages)
          .map(r -> r.resource)
          .toArray(String[]::new)
      );
    
      return IntStream
        .range(0, resourceData.length)
        .filter(i -> resourceUsages[i].role == role )
        .filter(i -> resourceData[i].basic.type == includeResourceType)
        .mapToObj(i -> resourceUsages[i])
        .toArray(ResourceUsage[]::new);
    }
    

    【讨论】:

      【解决方案3】:

      你可以用数组做这样的事情

      Arrays.stream(resourceUsages) 
                  .forEach(e->System.out.print(e));
      

      【讨论】:

        【解决方案4】:

        最好使用List&lt;ResourceUsage&gt; 而不是数组。

        我还要假装可以在每个资源上依次调用resourceToolkitAdapter.getData(),而不是批量调用。

        结果会是这样的:

            public List<ResourceUsage> filterResourceUsages(List<ResourceUsage> resourceUsages, int role, int includeResourceType)
                    throws SpiderException
            {
                return resourceUsages.stream()
                        .filter(r->r.role == role)
                        .filter(r->resourceToolkitAdapter.getData(r.resource).basic.type == includeResourceType)
                        .collect(Collectors.toList());
            }   
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-15
          • 1970-01-01
          • 2014-08-17
          • 2016-02-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多