Java中的并行分配?

Java中的并行分配?,java,Java,Java是否有类似于Python的[a,b,c]=(1,2,3)或PHP的列表($a,$b,$c)=数组(1,2,3)。这将创建一个分别具有值1、2和3的整数数组。实际上不是这样。您可以通过x=y=0设置多个变量,但不能像Python那样进行并行赋值。Python的多重赋值功能相当强大,因为它也可以用于并行赋值,如下所示: (x,y) = (y,x) # Swap x and y int a = 1, b = 2, c = 3; class Foo { public int a;

Java是否有类似于Python的
[a,b,c]=(1,2,3)
或PHP的
列表($a,$b,$c)=数组(1,2,3)
。这将创建一个分别具有值1、2和3的整数数组。

实际上不是这样。您可以通过
x=y=0
设置多个变量,但不能像Python那样进行并行赋值。

Python的多重赋值功能相当强大,因为它也可以用于并行赋值,如下所示:

(x,y) = (y,x) # Swap x and y
int a = 1, b = 2, c = 3;
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);
Java中的并行赋值没有等价物;您必须使用一个临时变量:

t = x; x = y; y = t;
您可以在一行中通过表达式指定多个变量,如下所示:

(x,y) = (y,x) # Swap x and y
int a = 1, b = 2, c = 3;
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);
或者要从数组映射,可以执行以下操作:

int a = array[0], b = array[1], c = array[2];
如果这看起来太冗长,您可以临时为分配创建一个对数组的单字母引用:

int[] t = array;
int a = t[0], b = t[1], c = t[2];
深入到问题的根源,在Python中,当代码在列表或数组中同时传递多个相关变量(可能是不同类型的变量)时,多重赋值往往很方便。在Java(或C/C++)中,更惯用的方法是创建一个小数据类(或结构)将这些变量捆绑在一起,并让生产者和消费者都使用它。然后可以按名称而不是索引引用字段,如下所示:

(x,y) = (y,x) # Swap x and y
int a = 1, b = 2, c = 3;
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);

这也为以后的重构打开了大门,这将使Foo成为一个具有行为和封装私有数据的真实类,而不仅仅是一个数据类。

将并行分配添加到Java并不困难,我们实际上在OptimJ语言扩展中实现了它。但它就是不在那里

正如Derrick提到的,原子交换语句需要并行赋值

你所说的并行赋值是一个更一般的概念“解构赋值”的实例:你有一些结构,你把它的一部分和变量匹配起来

假设您有嵌入式元组,则销毁赋值可以在任何级别提取数据:

(x, (y, z)) = ((1, 2, 3), (4, (5, 6)))
// x = (1, 2, 3)
// y = 4
// z = (5, 6)
假设您有一个列表或集合,则解构赋值可以提取子列表或子集(x表示元素,x*表示子列表):


显然,列表和集合可以嵌入元组。这个简单的方案提供了非常强大的编程抽象,在您需要提取数据时很有用。

{…
之前,您需要一个
新的int[]
,实际上您不需要
新的int[]
在数组初始值设定项之前,至少在数组初始值设定项是赋值的右侧时是这样。这与使用
x=0;y=0;
相同吗?我的意思是在JIT编译期间。基于左右求值,它应该是:
y=0;x=y;
否则,
x=y=new Object();
将实际创建两个对象?奇怪的是,我在问题或我的答案中的任何地方都找不到
新对象()
。在链接列表中的问题是:root.next=root.next.prev=newRoot与root.next.prev=root.next=newRoot相同。IntelliJ正在将此代码反编译为:
x=y=2