4

If you have an ArrayList (named al in this case), and you're looking to get the first five elements of the list as variables, you could do this:

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

However, using a for loop, is there a way you could do something like this instead:

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

Or is there a completely different method that is much more efficient?

  • 3
    If you have them in a list, why would you want them as separate variables? Why not just write `al.get(2)` any place you would write `x3`? If that's too verbose, you could put them in an array instead of a list (or just get an array from the list) and write `a[2]`. – David Conrad Feb 25 '15 at 20:59
  • Also, you can't do dynamic variables like what you're showing in Java. I mean, I suppose you could with reflection, but that is waaay overcomplicating this. – sma Feb 25 '15 at 21:00
  • No, not even reflection can mess with local variable names. Field names, maybe, but you have to declare all the field names up front – Louis Wasserman Feb 25 '15 at 21:01
  • @sma I think this was essentially the question I was asking, I just wasn't sure how to articulate it. I think my real question _was_ in fact "can you create dynamic variables in java". –  Feb 25 '15 at 21:01
  • The short answer is no, depending on what you are trying to achieve. You could copy the first five elements to a native array, but there is no point to that. – Prikso NAI Feb 25 '15 at 21:01
  • possible duplicate of [Dynamic variable names Java](http://stackoverflow.com/questions/5805843/dynamic-variable-names-java) – Raedwald Feb 27 '15 at 07:54

5 Answers5

5

Dynamic metaprogramming is not possible in java. Depending on what you are trying to achieve, there would be various options.

If you are trying to work in batches of 5 items, the cleanest solution is the one you are using now. If code duplication bothers you as much as it bothers me, then you are looking into Views in Java Collections Framework, specifically the "View of a portion of a collection" section:

List<String> nextFive = list.subList(5, 10);
Prikso NAI
  • 2,592
  • 4
  • 16
  • 29
  • Another option is apparently an associative array `Map props = new HashMap<>(); ... ; props.put("x"+i, al.get(i-1))`. But this code stinks and fetching by index alone from sublist is much cleaner. – harshtuna Feb 25 '15 at 21:29
3

You can have a String array of size 6 and do the following:

String[] str = new String[6];
for(int i=0; i<str.length; i++)
    a[i] = al.get(i);
HelloWorld
  • 1,128
  • 1
  • 7
  • 14
2

If you are trying to literally create variables on the local stack dynamically you would need to use reflection both ways (if it is even possible, which I don't think it is), otherwise it wouldn't compile then I would stick with the rule of thumb of Don't optimize unless you need to

If you are trying to create a reference to variables you can use a map

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

Then you can access like this

variables.get("x1"); //or x2,x3,x4
konkked
  • 3,161
  • 14
  • 19
  • I believe optimisation is going the other way around here, as @mrkalel is trying to roll an unrolled loop. It is mostly a matter of code replication. – Prikso NAI Feb 25 '15 at 21:02
  • @PriksoNAI see what you are saying, but the question asked for a more efficient way to declare local variables, and if repeating some code makes the code more maintainable then creating some obscure reflection based monster I would rather just deal with the replication to be honest – konkked Feb 25 '15 at 21:05
  • I hardly disagree, as the presented way is also the most efficient way already. I mere assume that there is a misalignment between the question's intentions and its title. – Prikso NAI Feb 25 '15 at 21:11
  • 1
    @PriksoNAI I updated the answer to answer what I think the OP wanted, basically can be done using a map – konkked Feb 25 '15 at 21:14
1

Why don't you just iterate through the ArrayList and break when you have reach the correct number of variables?

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

This, to my knowledge, is the quickest way to do it, since I believe the get() method is O(n). So expliciting writing a get() would prompt n! calls for the first n objects.

James Taylor
  • 6,158
  • 8
  • 48
  • 74
  • 1
    The `get` method in Java for an array list is `O( 1 )` get for linked list is `O( n )`, not a Java guy but think that the spinning up of the iterator also uses resources and you are not incrementing i in the answer – konkked Feb 25 '15 at 21:25
  • _The size, isEmpty, get, set, iterator, and listIterator operations run in constant time._ [http://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html] – harshtuna Feb 25 '15 at 21:35
1

"Perhaps" you don't want to do this in practice, but you could (all from within your program):

  1. write the boxed source code (String x1 = ...) as a proper class to a *.java file (with adjustments as needed)
  2. run the Java compiler to derive a corresponding *.class file
  3. class-load the class from that *.class file into your program and use it
Drux
  • 11,992
  • 13
  • 66
  • 116