Dart Map的怪异行为

时间:2019-11-24 12:46:49

标签: dart

我期望最后一个c

@Data
@Entity
@Table(name = "data_files")
public class DataFile {
    @Id
    @GeneratedValue
    @Setter(AccessLevel.NONE)
    private long identifier;

    @NotBlank
    @Column(name = "path")
    @RestResource(exported = false)
    private String path;

    @Embedded
    private Metadata metadata;

    public DataFile() {
        metadata = new Metadata();
    }

    public DataFile(Metadata metadata) {
        this.metadata = metadata;
    }
}

但实际上变成了

{a: {a: aA, b: aB}, b: {a: bA, b: bB}}

Dart代码:

{a: {a: bA, b: bB}, b: {a: bA, b: bB}}

其输出:

Map<String, String> a = {
  'a' : 'A',
  'b' : 'B',
};
Map<String, String> b = {};
Map<String, Map<String, String>> c = {};
void main() {
  for (var i in a.keys){
    for (var j in a.keys){
      b[j] = i+a[j];
      print('i: $i, j: $j, b[j]:${b[j]}');
    }
    print(b);
    c[i] = b;
    print(c);
  }
  print('final c is $c');
}

为什么会这样?

1 个答案:

答案 0 :(得分:2)

b映射插入c映射后,您将对其进行修改。我认为误解是因为您认为它是您放入c中的对象的副本,但实际上它是参考。如果打印hashCodea中的b,则可以看到它们实际上是同一对象:

print(c['a'].hashCode == c['b'].hashCode); // true

您真正想要的是在第一次循环的每次迭代中使用b的副本,因此代码如下:

Map<String, String> a = {
  'a': 'A',
  'b': 'B',
};

Map<String, Map<String, String>> c = {};

void main() {
  for (var i in a.keys) {
    Map<String, String> b = {}; // <-- this is the fix

    for (var j in a.keys) {
      b[j] = i + a[j];
      print('i: $i, j: $j, b[j]:${b[j]}');
    }
    print(b);
    c[i] = b;
    print(c);
  }
  print('final c is $c'); // {a: {a: aA, b: aB}, b: {a: bA, b: bB}}
  print(c['a'].hashCode == c['b'].hashCode); // false
}