简体   繁体   English

Java泛型-嵌套的foreach循环,删除重复的代码

[英]Java Generics - nested foreach loop, remove code duplication

I am attempting to remove some duplication from my code and by that, further my understanding of Java Generics. 我试图从我的代码中删除一些重复项,从而进一步了解Java泛型。

The following code snippet is contained in a class of generic type: 通用类型的类中包含以下代码片段:

ContainerClass<S1,S2,A>  

In one of the functions in this class i have encountered the need to iterate over two Set's as follows: 在此类的一个函数中,我遇到了如下迭代两个Set的需要:

for (SomeClass<S1,A> t1 : set1) {
    logic.setT1(t1);
    if(set2.isEmpty()) {
        logic.apply();
    } else {
        for(SomeClass<S2,A> t2 : set2) {
            logic.setT2(t2);
            logic.apply();
        }
    }
}

logic is just some class. logic只是一类。

The methods logic requires another iteration as follows: 方法逻辑需要再次迭代,如下所示:

for(SomeClass<S2,A> t2 : set2) {
    logic.setT2(t2);
    if(set1.isEmpty()) {
        logic.apply();
    } else {
        for (SomeClass<S1,A> t1 : set1) {
            logic.setT1(t1);
            logic.apply();
        }
    }
}

I am having some trouble with creating a method which could handle both cases per argument calls. 我在创建一个可以处理每个参数调用的两种情况的方法时遇到了一些麻烦。

Any help will be greatly appreciated, 任何帮助将不胜感激,
Thanks in advance. 提前致谢。

As requested, the following is the Logic class (an inner class): 根据要求,以下是Logic类(内部类):

private class Logic
{
    private Pair<S1,S2> currState;
    private Optional<Transition<S1,A>> t1;
    private Optional<Transition<S2,A>> t2;

    Logic()
    {
        init();
    }

    void setCurrState(Pair<S1,S2> currState)
    {
        this.currState = currState;
    }

    void setT1(Transition<S1,A> t1)
    {
        this.t1 = Optional.of(t1);
    }

    void setT2(Transition<S2,A> t2)
    {
        this.t2 = Optional.of(t2);
    }

    void apply()
    {
        if(t1.isPresent() && t2.isPresent()) {
            handleBoth();
        } else {
            handleSingle();
        }
        init();
    }

    private void add(Pair<S1,S2> to, A action)
    {
        if (!res.getStates().contains(to)){
            toReach.add(to);
            res.addState(to);
        }
        res.addAction(action);
        res.addTransition(new Transition<>(currState,action,to));
    }

    private void handleBoth()
    {
        var _t1 = t1.get();
        var _t2 = t2.get();

        if (_t1.getAction().equals(_t2.getAction()) && handshake.contains(_t1.getAction())) {
            add(Pair.pair(_t1.getTo(), _t2.getTo()), _t1.getAction());
        } else {
            handleSingle();
        }
    }

    private void handleSingle()
    {
        t1.ifPresent(_t1 -> {
            if(!handshake.contains(_t1.getAction())) 
                add(Pair.pair(_t1.getTo(),currState.second),_t1.getAction());
        });
        t2.ifPresent(_t2 -> {
            if (!handshake.contains(_t2.getAction()))
                add(Pair.pair(currState.first,_t2.getTo()),_t2.getAction());
        });
    }

    private void init()
    {
        t1 = Optional.empty();
        t2 = Optional.empty();
    }
}

It sounds like you would want to add some additional generics to Logic to make it Logic<S1, S2, A> , independently of the enclosing class. 听起来您想向Logic添加一些其他泛型,以使其独立于封闭类,使其成为Logic<S1, S2, A> Based on what you show, the logic is symmetrical and stateless enough that you can add the following method to Container : 根据显示的内容,逻辑是对称且无状态的,因此可以向Container添加以下方法:

public void <X1, X2> doTheThing(X1 set1, X2 set2)
{
    Logic logic = new Logic<X1, X2, A>();
    for (SomeClass<X1, A> t1 : set1) {
        logic.setT1(t1);
        if(set2.isEmpty())
            logic.apply();
        else
            for (SomeClass<S2,A> t2 : set2) {
                logic.setT2(t2);
                logic.apply();
            }
    }
}

Now you can call it with doTheThing(set1, set2) and doTheThing(set2, set1) . 现在,您可以使用doTheThing(set1, set2)doTheThing(set2, set1)来调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM