【问题标题】:Is there a more efficient way to create new variables in a for loop?有没有更有效的方法在 for 循环中创建新变量?
【发布时间】:2015-04-28 01:27:45
【问题描述】:

如果您有一个 ArrayList(在本例中名为 al),并且您希望将列表的前五个元素作为变量,您可以这样做:

    String x1 = al.get(0);
    String x2 = al.get(1);
    String x3 = al.get(2);
    String x4 = al.get(3);
    String x5 = al.get(4);

但是,使用 for 循环,有没有一种方法可以代替:

for (int i = 1; i < 6; i++){
    String namer = "x" + i.toString();
    String [value of String 'namer'] = al.get(i-1);
}

或者有没有更高效的完全不同的方法?

【问题讨论】:

  • 如果您将它们放在一个列表中,为什么要将它们作为单独的变量?为什么不在任何你想写x3 的地方写al.get(2)?如果这太冗长,您可以将它们放在一个数组而不是列表中(或者只是从列表中获取一个数组)并写a[2]
  • 另外,您不能像在 Java 中显示的那样做动态变量。我的意思是,我想你可以通过反思,但这太复杂了。
  • 不,即使是反射也不能与局部变量名混淆。可能是字段名称,但您必须预先声明所有字段名称
  • @sma 我认为这基本上是我要问的问题,我只是不确定如何表达它。我认为我真正的问题 实际上“你能在 java 中创建动态变量吗”。
  • 简短的回答是否定的,这取决于您要达到的目标。您可以将前五个元素复制到本机数组,但这没有意义。

标签: java for-loop arraylist


【解决方案1】:

如果您尝试在本地堆栈上动态地创建变量,则需要两种方式都使用反射(如果可能的话,我不认为是这样),否则它不会编译然后我会坚持 Don't optimize unless you need to的经验法则

如果您尝试创建对变量的引用,您可以使用映射

Map variables = new HashMap();
for (int i = 1; i < 6; i++) {
    variables.put("x"+i, al.get(i-1));
}

那你就可以这样访问了

variables.get("x1"); //or x2,x3,x4

【讨论】:

  • 我相信优化在这里是相反的,因为@mrkalel 正试图推出一个展开的循环。这主要是代码复制的问题。
  • @PriksoNAI 明白你在说什么,但问题要求一种更有效的方式来声明局部变量,如果重复一些代码使代码更易于维护,那么我宁愿创建一些基于反射的模糊怪物老实说,只需处理复制
  • 我几乎不同意,因为提出的方式也是最有效的方式。我只是假设问题的意图与其标题之间存在不一致。
  • @PriksoNAI 我更新了答案以回答我认为 OP 想要的,基本上可以使用地图完成
【解决方案2】:

“也许”你不想在实践中这样做,但你可以(全部来自你的程序):

  1. 将装箱的源代码 (String x1 = ...) 作为适当的类写入*.java 文件(根据需要进行调整)
  2. 运行 Java 编译器以派生对应的 *.class 文件
  3. *.class 文件中的类加载到您的程序中并使用它

【讨论】:

    【解决方案3】:

    动态元编程在 java 中是不可能的。根据您要达到的目标,会有多种选择。

    如果您尝试批量处理 5 个项目,最干净的解决方案就是您现在使用的解决方案。如果代码重复对您的困扰和对我的困扰一样多,那么您正在查看Views in Java Collections Framework,特别是“查看集合的一部分”部分:

    List<String> nextFive = list.subList(5, 10);
    

    【讨论】:

    • 另一个选项显然是关联数组Map&lt;Strinng,String&gt; props = new HashMap&lt;&gt;(); ... ; props.put("x"+i, al.get(i-1))。但是这段代码很臭,仅通过索引从子列表中获取要干净得多。
    【解决方案4】:

    为什么不遍历 ArrayList 并在达到正确数量的变量时中断?

    int i = 0;
    for (Object obj : al) {
        if (i > 5) { break; }
        results.append(obj); // append the first five elements to the result
    }
    

    据我所知,这是最快的方法,因为我相信get() 方法是 O(n)。所以明确写一个get() 会提示n!调用前 n 个对象。

    【讨论】:

    • Java 中用于数组列表的get 方法是O( 1 ) 获取链表是O( n ),不是Java 人,但认为迭代器的旋转也使用资源,而您没有在答案中增加 i
    • size、isEmpty、get、set、iterator 和 listIterator 操作在恒定时间内运行。 [docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html]
    【解决方案5】:

    您可以拥有一个大小为 6 的 String 数组并执行以下操作:

    String[] str = new String[6];
    for(int i=0; i<str.length; i++)
        a[i] = al.get(i);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2018-03-26
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多