在元素集列表中找到元素的属性

时间:2019-12-20 04:25:51

标签: java performance collections

我需要找到元素集列表中的元素键。有什么更好(更快)的方法呢?这是我的代码:

// get tags from an ArrayList of resources
boolean tagFound = false;
HashSet<Tag> resourceTags = new HashSet<>();
for (Resource resource : list) {
    Set<Tag> tmpTags = resource.getTags();
    resourceTags.addAll(tmpTags);
}

// get tag keys from all tags
for (Tag resourceTag : resourceTags) {
    if (resourceTag.getKey().equals(tag.getKey())) {
        tagFound = true;
        break;
    }
}

2 个答案:

答案 0 :(得分:0)

您可以将密钥而不是标签本身放在集合中,然后使用contains方法。下面的代码假定键是字符串。

Set<String> resourceTagKeys = new HashSet<>();
for(Resource resource : list) {
    for(Tag t : resource.getTags()) {
        resourceTagKeys.add(t.getKey());
    }
}
boolean tagFound = resourceTagKeys.contains(tag.getKey());

也就是说,如果您只是要测试一个元素,那么构建集合就没有多大意义。如果要测试多个键,则可以只构建一次该集合,然后使用单独的方法对其进行查询。否则,这种方法会更简单:

boolean tagFound = false;

outer:
for(Resource resource : list) {
    for(Tag t : resource.getTags()) {
        if(t.getKey().equals(tag.getKey())) {
            tagFound = true;
            break outer;
        }
    }
}

如果这是在返回tagFound的方法中进行的,则可以通过在循环中编写break来避免标记为return true;的情况。如果它不在方法中,则可以考虑对其进行重构,使其成为现实。

答案 1 :(得分:0)

如果您要做的就是在其上再次进行迭代以查找发生的情况,则可以免除addAll开销。

for (Resource resource : list) {
    for (Tag resourceTag : resource.getTags()) {
        if (resourceTag.getKey().equals(tag.getKey())) {
            tagFound = true;
            break;
        }
    }
}

如果要以功能性的方式编写,它看起来像:

boolean tagFound = list.stream()
        .flatMap(r -> r.getTags().stream())
        .anyMatch(t -> t.getKey().equals(tag.getKey()));

注意 :就性能而言,在 R x T 矩阵中,您必须支付O(R x T)运行时来搜索元素,除非它们被散列。在后一种情况下,例如,如果对Tag进行了哈希处理,则可以仅基于contains执行key来在O(1)中进行查找。