【问题标题】:Java Generics - nested foreach loop, remove code duplicationJava 泛型 - 嵌套 foreach 循环,去除代码重复
【发布时间】:2018-11-18 13:15:07
【问题描述】:

我正在尝试从我的代码中删除一些重复项,从而加深我对 Java 泛型的理解。

下面的代码sn-p包含在一个泛型类中:

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

【问题讨论】:

  • 忘了说,S1 和 S2 可能相等。
  • logic的类型是什么?
  • 在这种情况下,您需要将两种(可能)不同的logic.setT1()logic.setT2() 方法减少为一种通用的logic.set() 方法才能使用泛型。
  • 你可以分享logic类吗?
  • 这似乎是codereview.stackexchange.com 的一个案例,因为它是关于改进工作代码的。

标签: java generics set code-duplication


【解决方案1】:

听起来您可能想向Logic 添加一些额外的泛型以使其成为Logic&lt;S1, S2, A&gt;,独立于封闭类。根据您显示的内容,逻辑是对称且无状态的,您可以将以下方法添加到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) 调用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    相关资源
    最近更新 更多