如何在Java中同时更改多个主变量

时间:2016-04-13 15:37:41

标签: java methods scope

在我对Java的理解中,设置类对象的实例变量的最常用方法是:

  1. foo.setFooStuff(巴); //将一个setter方法放在类
  2. foo = modifyFooStuff(foo,bar); //传递&返回整个对象
  3. 让我们说我的main()有一个类bigA的对象,它包含一个类littleA对象(包含实例变量)的集合,以及类bigB的另一个对象,它包含类littleB对象的集合(它有来自littleA的不同实例变量)。如何编写一个方法来同时修改一个或多个littleA和littleB对象的实例变量?

    (注意:我怀疑这是一个常见的问题,但我搜索过但没有找到它。也许我使用了错误的术语。)

    编辑:更具体的例子:让我们说我是垄断者。玩家有钱(各种面额)和财产(有些有房子)。她想将一些房产升级到酒店。房屋和酒店都需要增加和减少金钱。我知道如何使用pass-by-reference语言执行此操作,但不使用pass-by-value,除非我将整个游戏状态转换为一个巨大的对象并传递它,这似乎是很多内存改组而且基本上和使用全局变量一样,这很糟糕,对吧?

3 个答案:

答案 0 :(得分:0)

如果我正确理解你的问题,你可以在bigA / bigB类上编写一个方法来获取你想要设置的值,然后遍历设置实例变量的littleA / B对象集合。像:

// Assuming Foo has a member collection of smallFoo
Foo A = new Foo();
// do stuff that populates the collection of smallFoo in A
A.setSmallFooZipCode("23444");
public void setSmallFooZipCode(String zip_ {
    // for thisSmallFoo in smallFoo
        thisSmallFoo.setZip(zip);
    // end for
)

答案 1 :(得分:0)

对象(包括你的容器对象)应该代表某些东西 - 用A / B来思考它们会让它变得有点困难。

最重要的是,如果你总是一次修改两个类中的属性,我会建议代码味道很差......

在我的脑海中,我无法想到任何我用这种方式建模的东西,所以很难想出一个例子。 A和B应该包含在父ab类中(并且该类应该具有该属性),或者a和b应该是相同的接口 - 在任何一种情况下,这些都将进入父容器中的单个集合。 / p>

所以说,你应该在父容器对象上有一个方法来完成工作。在大多数情况下,它不应该像“setAttribute ...”这样的方法,它应该是像“doAction”这样的方法。换句话说,如果你的容器是一个“Herd”并且它包含一堆大象,那么你会告诉Herd移动到某个位置并让Herd对象向每个大象发送消息告诉它去哪里。 / p>

如果你想到的方法是“要求对象为你做某事”而不是对某个对象进行操作,那么这有助于使这些决定变得更加容易。

答案 2 :(得分:0)

您只需将BigABigB封装在另一个对象中:

class BigWrapper {
    private BigA bigA;
    private BigB bigB;

    public void someMethod() {
        bigA.someMethod();
        bigB.someMethod();
    }
}
someMethod()中的

BigA会修改LittleA个实例。 BigB

相同
class BigB {
    private LittleA[] littles;

    public void someMethod() {
        //do something with the littles
    }
}

当然,此解决方案不允许您指定要定位的 Little 个实例,以及不会&#39 ; t允许您指定应该执行的行为(通过littles调用哪种特定方法)。

如果您想要这种灵活性,请使用回调:

interface Little { }
class LittleA implements Little { }
class LittleB implements Little { }

interface Callback<T extends Little> {
    void perform(int currentIndex, T currentLittle);
}

class CallbackHandler<T extends Little> {
    private int[] indexes;
    private Callback<T> callback;

    public CallbackHandler(int[] indexes, Callback<T> callback) {
        this.indexes = indexes;
        this.callback = callback;
    }

    public void perform(T[] littles) {
        for(int i = 0; i < indexes.length; i++) {
            int index = indexes[i];
            callback.perform(i, littles[index]);
        }
    }
}

class BigWrapper {
    private BigA bigA;
    private BigB bigB;

    public BigWrapper(BigA bigA, BigB bigB) {
        this.bigA = bigA;
        this.bigB = bigB;
    }

    public void perform(CallbackHandler<LittleA> aCallback, CallbackHandler<LittleB> bCallback) {
        bigA.perform(aCallback);
        bigB.perform(bCallback);
    }
}

class BigA {
    private LittleA[] littles;

    public BigA(LittleA[] littles) {
        this.littles = littles;
    }

    public void perform(CallbackHandler<LittleA> callback) {
        callback.perform(littles);
    }
}

class BigB {
    private LittleB[] littles;

    public BigB(LittleB[] littles) {
        this.littles = littles;
    }

    public void perform(CallbackHandler<LittleB> callback) {
        callback.perform(littles);
    }
}

CallbackHandler将实际回调映射到您要定位的索引。

所以你首先要创建回调:

Callback<LittleA> aCallback = (currentIndex, currentLittle) -> {
    //do what you want to the littles
};

然后将其传递给CallbackHandler,它允许您指定要定位的索引:

int[] indexes = { 0, 1, 2 };
CallbackHandler<LittleA> aCallbackHandler = new CallbackHandler<>(indexes, aCallback);

BigWrapper公开perform(CallbackHandler<LittleA>, CallbackHandler<LittleB>),因此您可以将处理程序传递给该方法。

MCVE看起来像:

public static void main(String[] args) {
    LittleA[] littleA = {
        new LittleA(),
        new LittleA(),
        new LittleA()
    };
    LittleB[] littleB = {
        new LittleB(),
        new LittleB(),
        new LittleB()
    };
    BigA bigA = new BigA(littleA);
    BigB bigB = new BigB(littleB);
    BigWrapper big = new BigWrapper(bigA, bigB);

    Callback<LittleA> aCallback = (index, little) -> {
        //...
    };
    Callback<LittleB> bCallback = (index, little) -> {
        //...
    };

    CallbackHandler aCallbackHandler = new CallbackHandler(new int[] { 2, 3, 4 }, aCallback);
    CallbackHandler bCallbackHandler = new CallbackHandler(new int[] { 5, 6, 7 }, bCallback);

    big.perform(aCallbackHandler, bCallbackHandler);
}