如何使用 Stream API 将 Object 类型的实例映射到 Java 中的特定类

How to map an instance of type Object to specific Class in Java using Stream API

提问人:TheBohne 提问时间:4/25/2022 最后编辑:Alexander IvanchenkoTheBohne 更新时间:4/25/2022 访问量:1250

问:

我遇到了以下问题:

如果我将流中的对象映射到 Java 中的特定类,则 java 流 API 在映射后无法识别特定对象,并且仍然假定它是一个对象。我做错了什么,有没有办法解决这个问题,而不会出现潜在的类转换异常?

下面是代码示例:

public class MyMapper {

        MyMapper() {
            Object someObject = new Person();
            final var listOfObjects = List.of(someObject);
            final var listOfPerson = toListOfPerson(listOfObjects);
        }

        List<Optional<Person>> toListOfPerson(Object object) {
            return ((List) object).stream()
                           .map(this::toPerson)
                           .collect(Collectors.toList());
        }

        Optional<Person> toPerson(Object object) {

            if (object instanceof Person) {
                return Optional.of((Person) object);
            }
            return Optional.empty();
        }

        public class Person {}
}
对象 转换 Java 流 映射

评论


答:

3赞 VeryNiceArgumentException 4/25/2022 #1

将其转换为类型化的 List,然后您的 .map(this::toPerson) 将“接受”此 List 的元素

List<Optional<Person>> toListOfPerson(Object object) {
            return ((List<Object>) object).stream()
                    .map(this::toPerson)
                    .collect(Collectors.toList());
    }
1赞 Alexander Ivanchenko 4/25/2022 #2

保留可能为空的可选对象的集合是没有意义的,它与存储值几乎相同。null

如果您出于某种原因认为这是个好主意,我建议您看看这个问题。引用 Stuart Marks(JDK 开发人员)的回答:List<Optional<Person>>

我敢肯定有人会想出一些人为的案例,他们 确实想将 Optional 存储在字段或集合中,但在 一般来说,最好避免这样做

Optional 是在 JDK 中引入的,作为表示可为 null 的返回值的有限机制。这是它的唯一目的,其他使用可选对象的情况,如可选方法参数、字段、可选集合被认为是反模式。

你必须在流中解压你的 s:Optional

public List<Person> toListOfPerson(Object object) {
    if (!(object instanceof List<?>)) {
        return Collections.emptyList();
    }
    
    return ((List<?>) object).stream()
        .map(this::toPerson)
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());
}

评论

0赞 TheBohne 4/25/2022
感谢您的详细回答。在我的用例中,对不存在的“人”进行了额外的处理。但我同意你的评论,只是抛出一个类强制异常,而不是使用可选。
0赞 Alexander Ivanchenko 4/25/2022
@TheBohne不存在的“人”的额外处理 - 然后,您可以考虑实现 Null 对象模式来处理这种情况。另请注意,instanceof 检查是一种代码气味。如果您正在使用返回对象的旧系统,这是可以理解的。但最好避免它,并以不需要类型检查和向下转换的方式设计逻辑。