Java 8 как упростить для l oop с помощью лямбда-выражений - PullRequest
4 голосов
/ 03 августа 2020

У меня есть этот метод в моем коде, и мне нужно упростить и сократить строки с помощью выражений 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-> do something);, но без списка в качестве ввода это кажется невозможным.

Есть ли какие-нибудь способ упростить этот код?

Ответы [ 4 ]

8 голосов
/ 03 августа 2020

вот исходные массивы и пакетное решение:

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);
}
4 голосов
/ 03 августа 2020

Вы можете сделать это с массивами

Arrays.stream(resourceUsages) 
            .forEach(e->System.out.print(e));
2 голосов
/ 03 августа 2020

В отличие от ответа Мэтью, я предполагаю, что resourceToolkitAdapter.getData() следует вызывать с пакетом идентификаторов.

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);
}
2 голосов
/ 03 августа 2020

Лучше всего использовать List<ResourceUsage>, а не массивы.

Я также сделаю вид, что можно вызывать 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());
    }   
...