java - 有没有更好/更通用的方法来解决动态转换?

标签 java generics java-stream

我有一个问题,我认为有更好的解决方案,但我不知道如何实现它。

我想映射一个类,例如从 Test2Message 到 MappedMessage。我的 API 在返回方法中仅提供通配符捕获(此处:MessageStream.getMessages())

现在我想解析消息并在 MappedMessage 中转换它们。有没有更好的方法来避免 .map(Runner::transform) 中的 if/else 映射?

如果我能实现一个方法就好了 MappedMessage transformWithCast(TestMessage testMessage)

让我们假设类 DomainMessage 和 MessageStream 无法调整/更改 - 在我的例子中,它们是框架的一部分,我无法更改任何内容。

public class Runner {

    public static void main(String[] args) {
        MessageStream messageStream = new MessageStream();
        messageStream.addMessage(new TestMessage());
        messageStream.addMessage(new Test2Message());

        List<MappedMessage> mappedMessages = messageStream.getMessages()
                .stream()
                .map(Runner::transform)
                // .map (Runner::transformWithCasr  how ?
                .collect(Collectors.toList());
    }

    /**
     * is there a more elegant solution for this?
     */
    private static MappedMessage transform(Object o) {
        if (o.getClass() == TestMessage.class) {
            return new MappedMessage("From TestMessage");
        }else if (o.getClass() == Test2Message.class) {
            return new MappedMessage("From Test2Message");
        }
    }

    /**
     * Is there a way , how to invoke this method from a Java stream map ?
     */
    private static MappedMessage transformWithCasr(TestMessage testMessage) {
        return new MappedMessage("From TestMessage");
    }



    static class DomainMessage {
        private String message;

        public DomainMessage(String message) {
            this.message = message;
        }
    }

    static class MessageStream {
        private List<DomainMessage> messages;

        public void addMessage(DomainMessage message) {
            this.messages.add(message);
        }

        public List<?> getMessages() {
            return this.messages;
        }
    }

    static class TestMessage extends DomainMessage {
        TestMessage() {
            super("Test Message");
        }
    }

    static class Test2Message extends DomainMessage {
        Test2Message() {
            super("Test 2 Message");
        }
    }

    static class MappedMessage {
        String value;

        MappedMessage(String value) {
            this.value = value;
        }
    }
}

最佳答案

我的猜测是,您可以通过模型委托(delegate)和多态性来实现这一点,这是比检查类更好的解决方案。

映射消息:

static abstract class DomainMessage {
    private String message;

    public DomainMessage(String message) {
        this.message = message;
    }
    public abstract MappedMessage toMappedMessage();
}

然后,实现

static class TestMessage extends DomainMessage {
    TestMessage() {
        super("Test Message");
    }

    public MappedMessage toMappedMessage() {
       return new MappedMessage("Test Message");
    }
}

所以,在你的流中,你只需要调用这个方法,它在每个继承自 DomainMessage 的类中实现

List<MappedMessage> mappedMessages = messageStream.getMessages()
            .stream()
            .map (DomainMessage::toMappedMessage)
            .collect(Collectors.toList());

希望这有帮助:)

关于java - 有没有更好/更通用的方法来解决动态转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57180917/

相关文章:

java - 泛型和 TreeSet

c# - 如何在 C# 中向非泛型类的构造函数添加泛型约束

java - 获取包含@Size注释的字段名称及其最大长度

Java 8 - 如何处理非基本类型的数组?

java - 流式传输迭代器的最简单方法

java - Gradle 使用源中的类作为打包阶段的一部分

java - 如何在java中取消定时的cron作业?

c# - 从泛型方法问题调用重载方法

java - Swagger-Codegen 不使用供应商扩展 x-discriminator-value

java - 解析包含动态 javascript 对象的网页