当前位置: 首页 > 知识库问答 >
问题:

将类转换为记录时的兼容性问题

澹台承载
2023-03-14
@ToString
@AllArgsConstructor
public class City {
    Integer id;
    String name;
}
record CityRecord(Integer id, String name) {} // much cleaner!

但是当我们转向这样的表示时,我们的一个单元测试开始失败。测试在内部处理从JSON文件读取并映射到对象的城市列表,进一步计算城市数,同时将它们分组到map中。简化为:

List<City> cities = List.of(
        new City(1, "one"),
        new City(2, "two"),
        new City(3, "three"),
        new City(2, "two"));
Map<City, Long> cityListMap = cities.stream()
        .collect(Collectors.groupingBy(Function.identity(),
                Collectors.counting()));

上面的代码断言为true,以包含4个键,每个键占其出现次数的1。使用记录表示法,生成的map中的键不超过3个。是什么造成了这种情况?应该采取什么办法来解决这种情况?

共有1个答案

锺离卓
2023-03-14

观察到的行为背后的原因如java.lang.Record中所述。

对于所有记录类,以下不变量必须成立:如果一个记录R的组件是c1、c2、...cn,那么如果一个记录实例复制如下:

 R copy = new R(r.c1(), r.c2(), ..., r.cn());   then it must be the case that r.equals(copy).

简而言之,您的CityRecord类现在有一个Equals(和hashcode)实现,该实现比较这两个属性,并确保如果它们相等,则由这些组件组成的记录也相等。作为这个评估的结果,具有相同属性的两个记录对象将被分组在一起。

record CityRecord(Integer id, String name) {

    // WARNING, BROKEN CODE
    // Does not adhere to contract of `Record::equals`
    @Override
    public boolean equals(Object o) {
        return this == o;
    }

    @Override
    public int hashCode() {
        return System.identityHashCode(this);
    }
}
 类似资料:
  • 但是当我们转向这样的表示时,我们的一个单元测试开始失败。测试在内部处理从JSON文件读取并映射到对象的城市列表,进一步计算城市数,同时将它们分组到中。简化为: 上面的代码断言为true,以包含4个键,每个键占其出现次数的1。使用记录表示法,生成的中的键不超过3个。是什么造成了这种情况?应该采取什么办法来解决这种情况?

  • 我试图编译一个从SourceForge得到的仍在开发中的项目。这是它的地址:。https://sourceforge.net/p/groove/code/5475/tree/groove/trunk/我知道这个项目经过了很好的验证,它没有任何错误,但是当我要编译它的时候,我遇到了这个编译错误: 错误在这个文件的第370行:https://sourceforge.net/p/groove/code/

  • Avro SpecificRecord(即生成的java类)是否与模式演化兼容?一、 e.如果我有一个Avro消息源(在我的例子中是Kafka),并且我想将这些消息反序列化为特定的记录,那么这样做是否安全? 我所看到的: 将字段添加到架构的末尾效果很好-可以将ok反序列化为specificrecord 在中间添加字段不会破坏现有客户机 即使消息兼容,这也是一个问题。 如果我能找到新的模式(例如使用

  • 我试图通过在一个单独的线程上进行工作并返回所需的对象来更改JavaFX中的GUI。然而,在完成工作和任务之后。setOnSucceeded()在尝试检索创建的对象时被触发,并出现错误“不兼容类型:对象无法转换为VideoScrollPane类型”。 我认为这与原始类型有关,因为这是在听众中发生的,但环顾四周后,我找不到我想要的建议。 任何可以散发的光芒都将不胜感激。

  • 问题内容: 一般来说,对于Java和编程,我是一个新手。我正在尝试创建一个简单的程序,您可以在其中猜测我的年龄,如果您是对的,它将说“正确”,如果您错了,它将说“错”。 这是我的代码: 我收到错误消息“不兼容的类型:void无法转换为int”,但代码中没有void类?我知道我的代码可能很糟糕,但是如果你们能为我指出正确的方向,那就太好了。谢谢。 问题答案: 您的程序不必返回in 。相反,您可以将其

  • 我试图在if语句中调用一个方法,但我总是得到以下错误。 不兼容的类型:java.lang.String不能转换为boolean