【问题标题】:Creating Custom POJOs to represent tree data创建自定义 POJO 来表示树数据
【发布时间】:2021-06-24 21:58:23
【问题描述】:

我想在 Java 8 中创建一系列自定义 POJO,以表示通过 JSON 接收和反序列化的数据结构。

数据看起来像(顶层向下)

RootNode
  <Set>LocalDate
    <Set>Location
       <Set>Shift
           Integer

例如,数据可能如下所示:

2021-06-20 
    AMBULANCE\CA\Los Angeles
        Morning
            4
        Afternoon
            5
        Nights
            5
    AMBULANCE\CA\San Deigo
        Afternoon
            7
        Nights
            6
        Morning 
            4
2021-06-21
     AMBULANCE\CA\Los Angeles
         Night
            6
         Morning
            5
         Afternoon
            5
     ANBULANCE\CA\San Francisco
         Afternoon
            5
         Morning
            4
....

在上面的结构中,每个日期都有几个子位置,每个位置有三个子班次,每个班次都有一个整数。

将其表示为我创建的 Java 对象:

public class RootNode {

    public RootNode(){}
    public LinkedHashMap<LocalDate, Location> locations;

}

public class Location {

   public Set<Shift> shifts;

}

public class Shift {

public enum ShiftTypes {
    MORNING, AFTERNOON, NIGHT
    }

    public Integer count;

}

不应有重复的日期、地点或员工。

这些类是否正确地代表了概述的数据结构?

所有这些类都是自定义的,除了 LocalDate 是本地的 - 我不确定是否要创建一个新的自定义日期类,它又具有 Set 属性?

如果这是设置结构的正确方法,那么语法是什么?使用扩展?

更新

我尝试使用以下方法扩展 LocalDate:

public class ShiftLocalDate extends LocalDate {

    public Set<Shift> shifts;

}

但由于LocalDate is final,这似乎无法完成?

【问题讨论】:

  • 我不清楚上下文。数据集代表什么?为什么你认为树结构适合这些数据?
  • 问题是创建的结构是否是在 java 中存储数据的最佳方式 - 至少在内存中时,并且 nbested 对象是否正确表示接收到的数据(通过 JSON)
  • 如果您的目标是用 Java 表示整个层次结构,那么此问题可能与以下内容重复:Represent tree hierarchy in java

标签: java


【解决方案1】:

扁平化层次结构

您的输入似乎代表一堆条目,这些条目被分组到日期 > 位置 > 班次层次结构中。

你的班级结构似乎过度紧张。根据您的应用程序的目标,您最好不要盲目地复制该层次结构。对于 Java 中的操作,将这些输入“重新水化”回一系列条目以扁平化层次结构似乎要简单得多。这些条目将是包含所有相关数据的类的对象。如果需要,您可以稍后从此类对象的集合中重新创建层次结构。

对于主要目的是透明且不可变地传递数据的类,在 Java 16+ 中,我们可以使用 records 特性。在一条记录中,您只需声明每个成员字段的类型和名称。编译器隐式创建构造函数、getter、equals & hashCodetoString

record WorkLogEntry ( LocalDate date , Location location , Shift shift , int countWorkers ) {} 

同样,定义一个适当的记录来表示Location。如果位置是在编译时完全已知的有限集合,请为它们创建一个枚举。

Shift 创建一个枚举,如您的问题所示。但是枚举对象是常量,所以按照约定应该全部大写。

enum Shift { MORNING , AFTERNOON , EVENING }

您可以访问enum object via a string。例如:

Shift.valueOf( "Afternoon".toUppercase( Locale.UK ) )

WorkLogEntry 类型的对象收集到一个集合中。也许使用NavigableSet 实现,例如TreeSet 来保持条目按日期排序。

Comparator< WorkLogEntry > comparator = Comparator.comparing( WorkLogEntry::date ).thenComparing( WorkLogEntry::location ).thenComparing( WorkLogEntry::shift ) ;
NavigableSet< WorkLogEntry > workLog = new TreeSet<>( comparator ) ;

如果您想按日期重新创建层次结构,请使用NavigableMap

NavigableMap< LocalDate , NavigableSet< WorkLogEntry > > map = new TreeMap<>() ;

【讨论】:

  • 抱歉更新了问题以更准确地反映数据结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
相关资源
最近更新 更多