【问题标题】:How to loop through variables without List如何在没有列表的情况下循环变量
【发布时间】:2017-10-25 05:07:04
【问题描述】:

如何在不使用数百个 if 的情况下循环和修改变量?

我目前有以下代码:

private int one = 5;
private int ten = 9;
private int hundred = 2;
private int thousand = 8;

public void checkBalance() {
    if (one > 1) {
        one *= 0.5;
    }
    if (ten > 1) {
        ten *= 0.5;
    }
    if (hundred > 1) {
        hundred *= 0.5;
    }
    if (thousand > 1) {
        thousand *= 0.5;
    }
}

然而,我想要一些方法来遍历这些变量并为每个变量做同样的事情。我不想使用 ArrayLists 和类似的东西,因为我需要它易于访问和阅读(例如,我调用 getOne、getHundred)

【问题讨论】:

  • 用你的设置,你不能。将它们放在某种数组/列表中。
  • 我不能,因为我也需要每个变量,这就是问题
  • 你可以通过反射来做到这一点。首先查找java.lang.Class 的文档。不要忘记放弃这个想法,当你意识到它比一开始就使用适当的数据结构会有更多的工作和混乱。特别是,如果您想按名称访问值,请考虑将它们存储在Map 的一种或另一种风格中。
  • 也许最好的办法是编写一个方法int f(int i) 并调用它one = f(one)。然而,最初的问题很可能比使用变量one, ... thousand 得到更好的解决。
  • int 乘以double 仅将结果存储在int 中?

标签: java android arrays variables methods


【解决方案1】:

经过一番反复试验,我终于得到了我想要的答案!

特别感谢 @John Bollinger 为我指明了正确的方向!

private String moneyValues = {"one", "ten", "hundred", "thousand"}

public void calculateBalance() {        
    for (int i = 0; i < moneyValues.length; i++) {
        if (getMoneyValue(moneyValues[i]) > 1) {
            setMoneyValue(moneyValues[i], getMoneyValue(moneyValues[i] * 0.5));
            break;
        }
    }

private int getMoneyValue(String variableName) {
    try {
        Class<?> c = getClass();
        return Integer.parseInt(c.getDeclaredField(variableName).get(this).toString());
    } catch (IllegalAccessException | NoSuchFieldException e) {
        e.printStackTrace();
    }
    return 0;
}

private void setMoneyValue(String variableName, int value) {
    try {
        Class<?> c = getClass();
        c.getDeclaredField(variableName).set(this, value);
    } catch (IllegalAccessException | NoSuchFieldException e) {
        e.printStackTrace();
    }
}

【讨论】:

    【解决方案2】:

    您似乎不想使用ArrayList,因为您想按名称访问每个变量,例如getOnegetHundred。在这种情况下,您应该使用 HashMap,它解决了迭代数百个变量以及变量可访问性的循环问题。

    这是您的问题的示例。

    HashMap<String, Integer> data = new HashMap<>();
    data.put("one", 5);
    data.put("ten", 9);
    data.put("hundred", 2);
    data.put("thousand", 8);
    

    这解决了你的循环问题...

    ArrayList<String> keys = new ArrayList<>(data.keySet());  //Get list of all keys
    for (int i = 0; i < keys.size(); i++) {     //iterate through keys
        if (data.get(keys.get(i)) > 1) {
            double temp = data.get(keys.get(i));  
            data.put(keys.get(i), (int)temp * 0.5);  //replace the original value
        }
    }
    

    这解决了您的变量可访问性问题...

    System.out.println(data.get("one"));
    System.out.println(data.get("ten"));
    

    【讨论】:

    • 很确定 OP 打算在您检查余额时收取您一半的钱(每个单元中的一个)。而且我认为我的银行很糟糕。
    【解决方案3】:

    我认为这是最好的方法:

    private int[] numbers = {5, 9, 2, 8};
    
    public void checkBalance() {
        for (int i = 0; i < numbers.length; i++) {
            if (numbers[i] > 1) {
                numbers[i] *= 0.5;
            }
        }
    }
    

    您可以通过这种方式获得任何价值:

    System.out.println(numbers[0]); // This will print 5
    System.out.println(numbers[1]); // This will print 9
    

    或者您可以获取所有值并将它们全部打印出来:

    for(int n : numbers){
        System.out.println(n); // This will print 5 9 2 8
    }
    

    更新:如果需要,您可以将列表位置分配给变量:

    private int one = numbers[0];
    private int ten = numbers[1];
    private int hundred = numbers[2];
    private int thousand = numbers[3];
    

    【讨论】:

    • 由于我需要多次更新,将列表位置分配给变量不会更新变量..
    【解决方案4】:

    您可以使用反射、代码生成或将所有变量放入类中的列表中。在你的例子中,我会更喜欢最后一个。我的意思是同时创建单独的变量和 thrm 列表

    【讨论】:

    • 反射和代码生成都过于复杂且难以维护。
    • 这就是为什么我说“在你的例子中我会选择最后一个。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 2018-08-05
    相关资源
    最近更新 更多