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

时间:2018-11-18 13:15:08

标签: java generics set code-duplication

我正在尝试从代码中删除一些重复项,从而进一步了解Java泛型。

以下代码段包含在通用类型的类中:

ContainerClass<S1,S2,A>  

在此类的一个函数中,我遇到了如下迭代两个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只是一门课。

方法逻辑需要再次迭代,如下所示:

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

我在创建一个可以处理每个参数调用的两种情况的方法时遇到了一些麻烦。

任何帮助将不胜感激,
提前致谢。

根据要求,以下是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();
    }
}

1 个答案:

答案 0 :(得分:0)

听起来,您可能想向Logic添加一些其他泛型以使其成为Logic<S1, S2, A>,而与封闭类无关。根据显示的内容,逻辑是对称且无状态的,因此可以向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();
            }
    }
}

现在您可以使用doTheThing(set1, set2)doTheThing(set2, set1)来调用它。