4

I have this method in my code and need o simplify and reduce lines by using java 8 expressions. Lambda can be used for this but it seems impossible without a list as input.

  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()]);
  }

I have tried using resourceUsages.forEach(resourceUsages.resource-> do something); but without list as input it seems impossible.

Is there any way to simplify this code?

2
  • 2
    "without list as input it seems impossible" ... Arrays.stream(myArray) Commented Aug 3, 2020 at 11:53
  • 1
    final List<String> ids = resourceUsages.stream().map(e -> e.resource).collect(toList()); Commented Aug 3, 2020 at 11:56

4 Answers 4

7

here is the origin arrays and batch solution:

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);
}
Sign up to request clarification or add additional context in comments.

Comments

3

You can do like this with arrays

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

Comments

2

It's best if you use List<ResourceUsage> rather than arrays.

I'm also going to pretend it's ok to call resourceToolkitAdapter.getData() on each resource in turn, rather than in bulk.

The result will be something like so:

    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());
    }   

Comments

2

Opposed to the answer of Matthew, I assume that resourceToolkitAdapter.getData() should be called with a batch of ids.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.