java 8 switch case默认为类类型的break [英] java 8 switch case default with break for class type

查看:308
本文介绍了java 8 switch case默认为类类型的break的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找java的切换类型,我在这里找到了一个解决方案:在java中切换类型

I was looking for switch over type for java, and I found a solution here: Switch over type in java

但问题是,解决方案不是真的像开关使用 break s,确定会发生这种情况,因为我循环遍历消费者,我想知道一个好方法修改我当前的代码或清除替代以便处理我的类类型,并且在处理首次匹配后中断,默认是处理不匹配的only(这里是父类 StripeObject )。

But the issue, solution was not really like a switch with breaks, sure this will happen because I loop over Consumers , I want to know a good way to modify my current code or clean alternative to have something to handle my class type, and break after handle first match and the default is to handle the unmatched only ( here it is the parent class StripeObject) .

我的业务是处理 webhooks ,我正在使用 stripe-java ,所以我的代码现在是这样的:

My business is to handle stripe events from webhooks, I'm using stripe-java, so my code now something like this:

    public void handleWebHookEvent(Event eventJson) throws CardException, APIException, AuthenticationException, InvalidRequestException, APIConnectionException {
        Stripe.apiKey = configuration.getString(AppConstants.STRIPE_API_KEY);

        // Verify the event by fetching it from Stripe
        Event event = Event.retrieve(eventJson.getId());
        Logger.debug(AppUtils.concatStrings("|-> Event Received: [", event.getId(), "] Type: [", event.getType(), "] Request ID: [", event.getRequest(), "]"));
        handleEventObject(event.getData().getObject());
    }

    private void handleEventObject(StripeObject stripeObject) {
        switchType(stripeObject,
                caze(Customer.class, this::handleEventObject),
                caze(Card.class, this::handleEventObject),
                caze(Charge.class, this::handleEventObject),
                caze(Transfer.class, this::handleEventObject)
                caze(StripeObject.class, object -> Logger.debug(AppUtils.concatStrings("|--> !!! Not Handled StripeObject !!! [", object.toString(), "]")))
        );
    }

    private void handleEventObject(Customer customer) {
        Logger.debug(AppUtils.concatStrings("|--> Customer ID <Description> : [", customer.getId(), " <", customer.getDescription(), ">]"));
    }

    private void handleEventObject(Card card) {
        Logger.debug(AppUtils.concatStrings("|--> Card ID <Brand> : [", card.getId(), " <", card.getBrand(), ">]"));
    }

    private void handleEventObject(Charge charge) {
        Logger.debug(AppUtils.concatStrings("|--> Charge ID <Description , Customer , Amount> : [", charge.getId(), " <", charge.getDescription(), " , ", charge.getCustomer() ," , ", charge.getAmount(), ">]"));
    }

    private void handleEventObject(Transfer transfer) {
        Logger.debug(AppUtils.concatStrings("|--> Transfer ID <Description , Destination , Amount> : [", transfer.getId(), " <", transfer.getDescription(), " , ", transfer.getDestination() ," , ", transfer.getAmount(), ">]"));
    }

    @SuppressWarnings("unchecked")
    private static <T> void switchType(StripeObject stripeObject, Consumer... consumers) {
        for (Consumer consumer : consumers)
            consumer.accept(stripeObject);
    }

    private static <T> Consumer caze(Class<T> clazz, Consumer<T> consumer) {
        return obj -> Optional.of(obj).filter(clazz::isInstance).map(clazz::cast).ifPresent(consumer);
    }

在当前代码中,如果evnet是以客户为例,它将打印:

In the current code, if the evnet was Customer as example it will print :

|--> Customer ID <Description> ... etc

然后

|--> !!! Not Handled StripeObject !!! ... etc

它必须只打印第一行,而不是第二行匹配。

It must print only the first line, not the second if match.

推荐答案

您只需要更改方法 switchType caze 使用谓词而不是消费者,所以循环可以停在第一场比赛。其余的代码不需要任何更改:

You only have to change the methods switchType and caze to use a Predicate instead of a Consumer, so the loop can stop at the first match. The rest of the code doesn’t need any change:

@SafeVarargs
private static void switchType(StripeObject so, Predicate<Object>... predicates) {
    for(Predicate<Object> predicate : predicates)
        if(predicate.test(so)) return;
}

private static <T> Predicate<Object> caze(Class<T> clazz, Consumer<T> consumer) {
    return obj -> {
        if(clazz.isInstance(obj)) {
            consumer.accept(clazz.cast(obj));
            return true;
        }
        return false;
    };
}

请注意,这仍然与开关不同语义,作为开关语句一般排除了模糊的情况。这里,其中一种类型仍然可以是另一种类型的子类型,因此,与开关语句不同, case 声明确实很重要。

Note that this still differs from the switch semantics, as a switch statement precludes ambiguous cases in general. Here, one of the types still could be a subtype of another, so, unlike a switch statement, the order of case statements does matter then.

如果所有情况都不同,这不是问题。

If all cases are distinct, this is not an issue.

这篇关于java 8 switch case默认为类类型的break的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆