Java 8映射与Map.get nullPointer优化

时间:2016-11-01 14:42:22

标签: optimization nullpointerexception functional-programming java-8

public class StartObject{
     private Something something;
     private Set<ObjectThatMatters> objectThatMattersSet;
}

public class Something{
     private Set<SomeObject> someObjecSet;
}

public class SomeObject {
     private AnotherObject anotherObjectSet;
}

public class AnotherObject{
     private Set<ObjectThatMatters> objectThatMattersSet;
}

public class ObjectThatMatters{
     private Long id;
}


private void someMethod(StartObject startObject) {
    Map<Long, ObjectThatMatters> objectThatMattersMap = StartObject.getSomething()
            .getSomeObject.stream()
            .map(getSomeObject::getAnotherObject)
            .flatMap(anotherObject-> anotherObject.getObjectThatMattersSet().stream())
            .collect(Collectors.toMap(ObjectThatMatters -> ObjectThatMatters.getId(), Function.identity()));
   Set<ObjectThatMatters > dbObjectThatMatters = new HashSet<>();
   try {
        dbObjectThatMatters.addAll( tartObject.getObjectThatMatters().stream().map(objectThatMatters-> objectThatMattersMap .get(objectThatMatters.getId())).collect(Collectors.toSet()));
    } catch (NullPointerException e) {
        throw new someCustomException();
    }
 startObject.setObjectThatMattersSet(dbObjectThatMatters);

给定一个包含一组ObjectThatMatters的StartObject a包含已获取的数据库结构的东西,其中包含所有有效的ObjectThatMatters。
何时我想将StartObject的ObjectThatMatters交换为仅存在于Something范围内的有效对应的db对象 然后我比较了StartObject上的ObjectThatMatters集合 用Something对象中的有效ObjectThatMatters替换它们中的每一个 如果某些ObjectThatMatters没有有效的ObjectThatMatters,我会抛出someCustomException

这个someMethod看起来非常可怕,我怎么能让它更具可读性呢?
已经尝试将尝试Catch更改为可选但实际上没有帮助。
由于性能的原因,使用Map而不是List with List.contains,这是一个好主意吗? ObjectThatMatters的总数通常为500 我不允许更改其他类结构,我只向您展示影响此方法的字段,而不是每个字段,因为它们是非常丰富的对象。

1 个答案:

答案 0 :(得分:1)

您根本不需要映射步骤。产生Map的第一个操作可用于首先生成所需的Set。由于可能存在比您感兴趣的对象更多的对象,因此您可以执行过滤操作。

首先,将所需对象的ID收集到一个集合中,然后收集相应的db对象,按Set ID过滤。您可以通过将生成的Set的尺寸与ID Set的尺寸进行比较来验证是否找到了所有ID。

private void someMethod(StartObject startObject) {
    Set<Long> id = startObject.getObjectThatMatters().stream()
        .map(ObjectThatMatters::getId).collect(Collectors.toSet());

    HashSet<ObjectThatMatters> objectThatMattersSet =
        startObject.getSomething().getSomeObject().stream()
            .flatMap(so -> so.getAnotherObject().getObjectThatMattersSet().stream())
            .filter(obj -> id.contains(obj.getId()))
            .collect(Collectors.toCollection(HashSet::new));

    if(objectThatMattersSet.size() != id.size())
        throw new SomeCustomException();

    startObject.setObjectThatMattersSet(objectThatMattersSet);
}

此代码生成HashSet;如果这不是一项要求,您只需使用Collectors.toSet()即可获得任意Set

甚至很容易找出缺少哪些ID:

private void someMethod(StartObject startObject) {
    Set<Long> id = startObject.getObjectThatMatters().stream()
        .map(ObjectThatMatters::getId)
        .collect(Collectors.toCollection(HashSet::new));// ensure mutable Set

    HashSet<ObjectThatMatters> objectThatMattersSet =
        startObject.getSomething().getSomeObject().stream()
            .flatMap(so -> so.getAnotherObject().getObjectThatMattersSet().stream())
            .filter(obj -> id.contains(obj.getId()))
            .collect(Collectors.toCollection(HashSet::new));

    if(objectThatMattersSet.size() != id.size()) {
        objectThatMattersSet.stream().map(ObjectThatMatters::getId).forEach(id::remove);
        throw new SomeCustomException("The following IDs were not found: "+id);
    }

    startObject.setObjectThatMattersSet(objectThatMattersSet);
}