Parallel assignment in Java?
Asked Answered
M

4

22

Does Java have something similar to Python's [a, b, c] = (1, 2, 3) or PHP's list($a, $b, $c) = array(1, 2, 3)?

Morningglory answered 6/5, 2011 at 22:29 Comment(0)
H
11

Not really. You can do x = y = 0 to set several variables, but not a parallel assignment like Python.

Holiness answered 6/5, 2011 at 22:31 Comment(5)
Is this same as using x = 0; y = 0;? I mean during JIT-compilation.Odometer
Based on right-left evaluation, it should be: y = 0; x = y; Otherwise, x = y = new Object(); will actually create two objects?Plover
Oddly, I can't find a new Object() anywhere in the question or my answer.Holiness
Question, in a linked list is: root.next = root.next.prev = newRoot the same as root.next.prev = root.next = newRoot ?Tesch
IntelliJ is decompiling this code: x = y = 2 into this: int y = 2; int x = 2;Purapurblind
P
9

Python's multiple assignment is fairly powerful in that it can also be used for parallel assignment, like this:

(x,y) = (y,x) # Swap x and y

There is no equivalent for parallel assignment in Java; you'd have to use a temporary variable:

t = x; x = y; y = t;

You can assign several variables from expressions in a single line like this:

int a = 1, b = 2, c = 3;

Or to map from an array, you can do this:

int a = array[0], b = array[1], c = array[2];

If this seems too verbose, you can temporarily create a one-letter reference to your array for the assignment:

int[] t = array;
int a = t[0], b = t[1], c = t[2];

Getting more to the root of the question, multiple assignment tends to be handy in Python in situations where code is passing around several related variables (perhaps of different types) together in a list or array. In Java, it's more idiomatic to do this with a small data class that bundles these variables up together, and have both the producer and consumer use it. You can then refer to the fields by name instead of by index:

class Foo {
    public int a;
    public int b;
    public int c;
}

/* ... */

Foo produceFoo() {
    Foo f = new Foo();
    f.a = 1;
    f.b = 2;
    f.c = 3;
    return f;
}

/* ... */

Foo f = produceFoo();
System.out.println(f.a + "," + f.b + "," + f.c);

This also opens the door to later refactoring that will make Foo a real class with behavior.

Java 16+ Update: If you are using Java 16+ you can also use record types to do this same approach more succintly:

record FooResult(int a, int b, int c) { }

FooResult produceFoo() {
    return new FooResult(1, 2, 3);
}

/* ... */

var f = produceFoo();
System.out.println(f.a + "," + f.b + "," + f.c);
Provisional answered 6/5, 2011 at 22:51 Comment(0)
H
2

Try int[] list = {1,2,3}. This creates an integer array with values 1, 2 and 3 respectively.

Housemaster answered 6/5, 2011 at 22:31 Comment(2)
you'd need a new int[] before the {...Liar
Actually you don't need a new int[] before the array initializer, at least not when the array initializer is the right-hand side of an assignment.Stalkinghorse
S
2

Parallel assignment wouldn't be difficult to add to Java, we actually implemented it in our OptimJ language extension. But it just isn't there.

As Derrick mentions, parallel assignment is required for an atomic swap statement.

What you call parallel assignment is an instance of a more general concept called "destructuring assignment": you have some structure, and you match parts of it to variables.

Suppose you have embedded tuples, then destructing assignment can extract data at any level:

(x, (y, z)) = ((1, 2, 3), (4, (5, 6)))
// x = (1, 2, 3)
// y = 4
// z = (5, 6)

Suppose you have a list or a set, then destructuring assignment can extract sublists or subsets (x stands for an element, x* stands for a sublist):

[ x, y*, z ] = [ 1, 2, 3, 4 ]
// x = 1
// y = [ 2, 3 ]
// z = 4

Obviously lists and sets can be embedded with tuples. This simple scheme provides very powerful programming abstractions, useful as soon as you need to extract data.

Scarcity answered 9/5, 2011 at 16:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.