根据条件(Java / Guava)从列表中提取第一个匹配项?

时间:2014-03-26 10:18:43

标签: java functional-programming guava

我有以下对象的列表:

class ResourcePermissionDTO {
  PermissionType permissionType;
  ... 
}

其中PermissionType是以下枚举:

public enum PermissionType {
   DENY, READ_ONLY, READ_WRITE;
}

因此,列表如下:

List<ResourcePermissionDTO> myResourcePermissions = ...

我想要的是返回myResourcePermissions中找到的第一个具有最严格权限的ResourcePermissionDTO。目前我有以下内容,但它有点乱,我可能有更好的方法使用谷歌番石榴/功能习语吗?

private ResourcePermissionDTO returnTheFirstMostRestrictivePermissionFoundIn(final List<ResourcePermissionDTO> resourcePermissionDTOs) {
    if (resourcePermissionDTOs.isEmpty()) {
      return null;
    }

    final List<ResourcePermissionDTO> resourcePermissionDTOsWithReadWritePermissionOfDeny = Lists.newArrayList();
    final List<ResourcePermissionDTO> resourcePermissionDTOsWithReadWritePermissionOfReadOnly = Lists.newArrayList();
    final List<ResourcePermissionDTO> resourcePermissionDTOsWithReadWritePermissionOfReadWrite = Lists.newArrayList();

    for (final ResourcePermissionDTO resourcePermissionDTO : resourcePermissionDTOs) {
      switch (resourcePermissionDTO.getPermissionType()) {
      case DENY:
        resourcePermissionDTOsWithReadWritePermissionOfDeny.add(resourcePermissionDTO);
        break;
      case READ_ONLY:
        resourcePermissionDTOsWithReadWritePermissionOfReadOnly.add(resourcePermissionDTO);
        break;
      case READ_WRITE:
        resourcePermissionDTOsWithReadWritePermissionOfReadWrite.add(resourcePermissionDTO);
        break;
      default:
        break;
      }
    }

    if (!resourcePermissionDTOsWithReadWritePermissionOfDeny.isEmpty()) {
      return resourcePermissionDTOsWithReadWritePermissionOfDeny.get(0);
    } else if (!resourcePermissionDTOsWithReadWritePermissionOfReadOnly.isEmpty()) {
      return resourcePermissionDTOsWithReadWritePermissionOfReadOnly.get(0);
    } else if (!resourcePermissionDTOsWithReadWritePermissionOfReadWrite.isEmpty()) {
      return resourcePermissionDTOsWithReadWritePermissionOfReadWrite.get(0);
    } else {
      return null;
    }
  }

2 个答案:

答案 0 :(得分:1)

即使在命令式风格中,也可简化如下:

List<ResourcePermissionDTO> permissions = ...;
ResourcePermissionDTO result = null;

for (ResourcePermissionDTO p: permissions) {
    if (result == null || isStronger(p.getPermissionType(), result.getPermissionType())) {
        result = p;
        if (result.getPermissionType() == PermissionType.DENY) break; // (1)
    }
}

return result;

如果您更喜欢功能样式,则可以使用(1)重现完全相同(尽管没有reduce()处的短路优化)。 Guava不支持reduce(),因此以下示例在Java 8中:

return permissions.stream().reduce((result, p) -> {
    return isStronger(p.getPermissionType(), result.getPermissionType()) ? p : result;
}).orElse(null);

答案 1 :(得分:1)

我该怎么做

  1. 使ResourcePermissionDTO实施Comparable<ResourcePermissionDTO>
  2.  class ResourcePermissionDTO implements Comparable<ResourcePermissionDTO> {
          PermissionType permissionType;
          @Override
          public int compareTo(ResourcePermissionDTO that) {
              return this.permissionType.compareTo(that.permissionType);
          }
        }
    
    1. 将所有DTO添加到单个列表中

      List<ResourcePermissionDTO> myResourcePermissions =

    2. 使用Guava的Ordering从列表中获取第一项

      ResourcePermissionDTO leastRestrictive = Ordering.natural().max(myResourcePermissions);