【问题标题】:Is it possible to declare reference variables in for or while loop?是否可以在 for 或 while 循环中声明引用变量?
【发布时间】:2019-05-27 18:53:06
【问题描述】:

我编写了一个简短的代码,从名为“ChosenCompanies”的类中声明了 6 个引用变量,以练习 Java 中的类和构造函数。

如下:

public static void main(String[] args) {

    String[] FinalCompaniesName = new String[6];

    ChosenCompanies com1 = new ChosenCompanies();
    ChosenCompanies com2 = new ChosenCompanies();
    ChosenCompanies com3 = new ChosenCompanies();
    ChosenCompanies com4 = new ChosenCompanies();
    ChosenCompanies com5 = new ChosenCompanies();
    ChosenCompanies com6 = new ChosenCompanies();

    Scanner scanner = new Scanner(System.in);
    int choice;
    int count = 1;
    while(count <= 2) {
        switch(count) {
        case 1:
            System.out.println("Choose one:");
            System.out.println("1. " + com1.name);
            System.out.println("2. " + com2.name);
            System.out.println("3. " + com3.name);
            choice = scanner.nextInt();
            switch(choice) {
            case 1:
                FinalCompaniesName[0] = com1.name;
                break;
            case 2:
                FinalCompaniesName[0] = com2.name;
                break;
            case 3:
                FinalCompaniesName[0] = com3.name;
                break;
            }
        break;
        case 2:
            System.out.println("Choose one:");
            System.out.println("1. " + com4.name);
            System.out.println("2. " + com5.name);
            System.out.println("3. " + com6.name);
            choice = scanner.nextInt();
            switch(choice) {
            case 1:
                FinalCompaniesName[1] = com4.name;
                break;
            case 2:
                FinalCompaniesName[1] = com5.name;
                break;
            case 3:
                FinalCompaniesName[1] = com6.name;
                break;
            }
            break;
        }    
        count++;
    }
        System.out.println("You have chosen: "
 + FinalCompaniesName[0] + ", " + FinalCompaniesName[1]);

}

从上面的代码可以看出,这两部分除了引用变量的名字(com1, com2, com3, com4...)之外几乎是一样的:

第 1 部分:

        switch(count) {
        case 1:
            System.out.println("Choose one:");
            System.out.println("1. " + com1.name);
            System.out.println("2. " + com2.name);
            System.out.println("3. " + com3.name);
            choice = scanner.nextInt();
            switch(choice) {
            case 1:
                FinalCompaniesName[0] = com1.name;
                break;
            case 2:
                FinalCompaniesName[0] = com2.name;
                break;
            case 3:
                FinalCompaniesName[0] = com3.name;
                break;
            }
         break;

第 2 部分:

        case 2:
            System.out.println("Choose one:");
            System.out.println("1. " + com4.name);
            System.out.println("2. " + com5.name);
            System.out.println("3. " + com6.name);
            choice = scanner.nextInt();
            switch(choice) {
            case 1:
                FinalCompaniesName[1] = com4.name;
                break;
            case 2:
                FinalCompaniesName[1] = com5.name;
                break;
            case 3:
                FinalCompaniesName[1] = com6.name;
                break;
                }
            break;
        }    

我想知道是否可以通过使用 for 或 while 循环来最小化上述代码的数量,因为引用变量的名称会增加 1,就像常见 for 语句中的整数“i”一样。

简而言之,是否可以通过循环来声明引用变量?

【问题讨论】:

  • 使该部分成为将这 3 个对象作为参数的方法。
  • 第二部分的代码会被执行吗?您的while 条件仅在count &lt; 2 时通过,case 2 部分将如何运行?
  • 是的,第 2 部分中的代码已执行,我在几秒钟前检查了结果。我和你有同样的疑问,一开始就设置了 while 条件(count
  • 我知道为什么要执行代码了;这是因为我没有为 switch(count) 语句添加 break 语句。我修复了原始代码,因为它很混乱。
  • 请注意,您应该遵循 Java 命名约定:变量名总是以驼峰命名。所以FinalCompaniesName 应该是finalCompaniesName

标签: java


【解决方案1】:

您的示例令人困惑,因此我不知道您到底想完成什么,但这里有一个示例,说明如何提示用户从现有公司名称列表中为每个公司选择一个新名称:

    public class Company {

    /**
     * Array of available company names used to construct
     * initial companies. These names are also used as possible
     * choices when changing company names through {@link #changeCompanyNames()}
     */
    private static final String[] COMPANY_NAMES = new String[]
            { "Alphabet", "Microsoft", "IBM", "Amazon", "Oracle", "Apple" };

    /**
     * <p>
     * Array of Company objects initialized with a fixed number of
     * new companies equal to the number of String entries in {@link #COMPANY_NAMES}.
     * </p><p>
     * Each company entry will inheriting a name from the mentioned array
     * in the initialization process done in {@link #initializeCompanies()}
     * </p>
     */
    public static final Company[] COMPANIES = initializeCompanies();

    private String name;

    /**
     * Internal constructor with private access to
     * prevent class construction outside this class
     */
    private Company(String name) {
        this.name = name;
    }

    /**
     * Should only be used internally on class loading to
     * construct an array of companies from a list of company names.
     */
    private static Company[] initializeCompanies() {

        Company[] companies = new Company[COMPANY_NAMES.length];
        for (int i = 0; i < COMPANY_NAMES.length; i++) {
            companies[i] = new Company(COMPANY_NAMES[i]);
        }
        return companies;
    }

    /**
     * Change any or all company names by prompting the user to choose
     * a new name for each company from the list of available companies.
     */
    public static void changeCompanyNames() {

        java.util.Scanner scanner = new java.util.Scanner(System.in);
        /*
         * Create a new array of company names that is identical to the existing
         * array of company names. We will change names here on user input and
         * then update each new company name to values from this array.
         */
        final String[] finalCompanyNames = COMPANY_NAMES.clone();
        /*
         * Iterate through an array of companies with a for-loop
         * accessing and processing each company entry
         */
        for (int i1 = 0; i1 < COMPANIES.length; i1++)
        {
            /* Prompt the user to choose a new company name for the
             * company at index i1 from COMPANIES array.
             */
            System.out.printf("Choose a new company name for %s company:%n", COMPANIES[i1].name);
            /*
             * Again iterate through all companies and print their names to
             * console offering the user a list of possible names to choose from
             */
            for (int i2 = 0; i2 < COMPANIES.length; i2++) {
                System.out.printf("%d. %s%n", i2 + 1, COMPANIES[i2].name);
            }
            /*
             * Get user input and validate it, then either update the array of
             * final names with the new entry or print an error and move the index
             * to the previous position if the input was an invalid number
             */
            int input = scanner.nextInt();
            if (input > 0 && input <= COMPANIES.length) {
                finalCompanyNames[i1] = COMPANY_NAMES[input - 1];
                System.out.println("You have choosen company name " + finalCompanyNames[i1]);
            }
            else {
                System.out.printf("Error: input is not in range (1-%d)%n", COMPANIES.length);
                /*
                 * It's imperative that we move the index to the previous
                 * position so we can iterate over this company entry again
                 */
                i1 -= 1;
            }
        }
        // Print simple line separator
        System.out.println("");

        /* Print each choosen name that is different then the original
         * company name and update the appropriate company name field value
         */
        for (int i = 0; i < finalCompanyNames.length; i++)
        {
            if (!finalCompanyNames[i].equals(COMPANY_NAMES[i])) {
                System.out.printf("Company %s has changed name to %s%n", COMPANY_NAMES[i], finalCompanyNames[i]);
                COMPANIES[i].name = finalCompanyNames[i];
            }
        }
    }
}

用户完成选择后的控制台输出示例:

Company Alphabet has changed name to IBM
Company Microsoft has changed name to Amazon
Company IBM has changed name to Alphabet
Company Amazon has changed name to Oracle
Company Oracle has changed name to Microsoft
Company Apple has changed name to Amazon

在这里,我们可以设置任意数量的公司,并让用户为他们选择任何提供的名称。对于初学者来说,这段代码可能看起来有点令人生畏,但这实际上是最简单的方法,无需涉及任何更复杂的 Java 概念。

请随时询问有关此实施的任何问题。我很乐意提供帮助。

编辑:更新了代码以包含详细的 cmets 和更易于理解的更全面的结构,并修复了索引问题。

【讨论】:

  • 嗨,马修。感谢新的实施和解释。我现在正试图理解你的代码,我相信一旦我读完它会对我有很大帮助。我现在有一个问题:“ChosenCompanies[] 公司”是什么意思?我认为 ChosenCompanies 是当前类的名称,而 [] 用于数组(至少从我目前所学的内容来看),所以整个表单 - “ChosenCompanies [] 公司” - 让我感到困惑。你能给我一些关于那条线的提示,以便我可以用谷歌搜索它并进一步了解吗?提前谢谢你:)
  • 我更新了代码以包含详细的 cmets 和更易于理解的更全面的结构,因此现在应该更清楚了。关于您关于该数组的问题,它只是一个名为Company 的自定义类的简单对象数组,我建议您阅读此处提供的有关数组的官方教程:docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html。这可能是开始了解更多有关数组的好地方。
  • 如果您觉得我的回答提供了对处理简单数组的基本方法的更多见解,并且总体上更好地解决了您的问题,请随意选择我的答案作为接受的答案。我对实际积极参与该网站还比较陌生,并且对我的第一个接受的答案感到非常满意。
  • 你的回答真的很有帮助而且写得很好,我在检查代码中的 cmets 时学到了很多东西。但是,当我运行您的程序并插入“6”以选择 Apple 作为公司名称时,它显示“错误:输入不在范围 (1-%d)%n 内”。我修复了一点(输入 > 0 && 输入 + 1),现在它在我的机器上运行良好,但我认为很高兴告诉你这一点,因为我想要在不违反不建议我们只写“谢谢”评论的论坛规则的情况下说“感谢您提供如此彻底的回答”。 :)
  • 很高兴能帮上忙,感谢您接受我的回答。我已经修复了发布的代码,并建议使用input &gt; 0 &amp;&amp; input &lt;= COMPANIES.length 而不是input &gt; 0 &amp;&amp; input &lt; COMPANIES.length + 1,因为它更干净一些。
【解决方案2】:

在 Java 中无法创建动态变量(但使用反射,请参阅 here

您可以创建一个数组并使用i 作为索引,如chosenCompanies[i]

否则您可以使用列表或地图。

编辑:

那将是例如看起来像这样。除了代码的意义,这个例子只展示了如何使用数组:

    String[] choosenCompanieNames = new String[2]; // you only store two values, not 6 values

    //lets store the values to chose in arrays
    String[] possibleCompanieNames = new String[6]; // 6 possible values to choose (com1 - com6)
    possibleCompanieNames[0] = "com1";
    possibleCompanieNames[1] = "com2";
    possibleCompanieNames[2] = "com3";
    possibleCompanieNames[3] = "com4";
    possibleCompanieNames[4] = "com5";
    possibleCompanieNames[5] = "com6";

    //I deleted the while loop, as it only has two ways and every way has its own code. 

    Scanner scanner = new Scanner(System.in);
    int choice;

    System.out.println("Choose one:");
    System.out.println("1. " + possibleCompanieNames[0]);
    System.out.println("2. " + possibleCompanieNames[1]);
    System.out.println("3. " + possibleCompanieNames[2]);
    choice = scanner.nextInt();
    choosenCompanieNames[0] = possibleCompanieNames[choice-1]; //you must subtract one, as the array index starts at 0 and ends on 5

    System.out.println("Choose one:");
    System.out.println("1. " + possibleCompanieNames[3]);
    System.out.println("2. " + possibleCompanieNames[4]);
    System.out.println("3. " + possibleCompanieNames[5]);
    choice = scanner.nextInt();
    choosenCompanieNames[1] = possibleCompanieNames[3+choice-1]; //here you want com4, com5 and com6, so you can e.g. add 3 to index and substract one like code above. Or better add only 2, as 3-1=2


    System.out.println("You have chosen: "
         + choosenCompanieNames[0] + ", " + choosenCompanieNames[1]);

【讨论】:

  • 感谢您的回答。但是由于我一个月前才开始学习 Java,所以我不明白你提到的数组与我有什么关系。你的意思是存储引用变量的数组吗? (我想知道是否可能)或者您的意思是从名为“chosenCompanies”的数组中命名引用变量,如“chosenCompanies[i]”?(我也想知道是否可能)
  • Eunyoung,您已经在代码中证明您知道如何声明和创建数组;因为您已经使用finalCompaniesName 完成了它。现在您所要做的就是与chosenCompanies 完全相同。
  • 查看我的编辑。它展示了如何使用数组执行此操作的一种方法。
  • 我看到了你的编辑。我认为我如此困惑的原因是因为我仍然想创建动态变量并神奇地最小化代码量,即使在阅读了你说这是不可能的答案之后(除非我使用反射)。但是,在检查编辑后,您使用数组存储可能的公司名称的方式是有意义的,并且我可以更容易地维护代码,因为我可以在顶部看到存储的值。谢谢。
猜你喜欢
  • 1970-01-01
  • 2018-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
相关资源
最近更新 更多