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

时间:2019-07-24 10:37:13

标签: java generics java-stream

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

我想映射一个类,例如从Test2Message到MappedMessage。我的API在return方法中仅提供通配符捕获(此处: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;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

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

映射的消息:

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());

希望获得帮助:)