[英]Change “perspective” of multi-dimension tree
|-- Car |-- Green
| |-- Audi | |-- Car
| | |-- Green | | `-- Audi
| | |-- Blue | `-- Bike
| | `-- Red | `-- BMW
| `-- BMW |-- Blue
| |-- Red | `-- Car
| `-- Yellow ==========> | `-- Audi ==========> etc.
`-- Bike |-- Red
|-- BMW | |-- Car
| |-- Yellow | | |-- Audi
| |-- Blue | | `-- BMW
| `-- Green | `-- Bike
`-- Honda | `-- Honda
|-- Red `-- Yellow
`-- Yellow |-- Car
| `-- BMW
`-- Bike
|-- BMW
`-- Honda
I want to implement several "perspectives" in a tree builder, in a generic fashion . 我想以通用的方式在树构建器中实现几个“视角”。
There are 6 possible permutations of this tree, I've just drawn 2 of them. 该树有6个可能的排列,我刚刚画了其中的2个。
What I tried: 我试过的
TreeBuilder
, AbstractNode
, VehicleNode
, ColorNode
, MakerNode
, and another ordered list of enums which defines the order of the levels: BY_VEHICLE
, BY_COLOR
, BY_MAKER
- you switch these around to get desired perspective 类: TreeBuilder
, AbstractNode
, VehicleNode
, ColorNode
, MakerNode
以及另一个定义级别顺序的枚举的有序列表: BY_VEHICLE
, BY_COLOR
, BY_MAKER
您可以切换它们以获得所需的视角 enumValue
, while passing the tree builder, and the parentEnumValue
(for a top-level, the parent enum value is NULL). 使用工厂方法,使用enumValue
,同时传递树构建器和parentEnumValue
(对于顶级,父枚举值是NULL)来创建节点。 getParentMember_Internal
which fetches the corect parent based on parentEnumValue
(by using the treeBuilder
which contains all the data mappings) 子级有一个getParentMember_Internal
,它基于parentEnumValue
获取corect父parentEnumValue
(通过使用包含所有数据映射的treeBuilder
) Why it doesn't work: 为什么不起作用:
What I'm asking: 我要问的是:
EDIT 1 @Andreas 编辑1 @Andreas
There are only 3 possible entities in the tree: Vehicle
, Color
, Maker
. 树中只有3种可能的实体: Vehicle
, Color
, Maker
。 There is not "vehicle type". 没有“车辆类型”。 All payloads in the tree are subclasses of these three. 树中的所有有效载荷都是这三个的子类。
I call them "payloads", because each object is wrapped in a AbstractNode
subclass (which is part of a tree structure) to separate the data from the presentation layer. 我称它们为“有效载荷”,因为每个对象都包装在AbstractNode
子类(树结构的一部分)中,以将数据与表示层分开。 Example: VehicleNode has a Vehicle payload
. 示例: VehicleNode has a Vehicle payload
。
Since the entities are independent from eachother, levels may be hidden. 由于实体彼此独立 ,因此级别可能被隐藏。 This would be a valid case: 这是一个有效的情况:
|-- Green
| |-- Audi
| `-- BMW
|-- Blue
| `-- Audi
|-- Red
| |-- Audi
| |-- BMW
| `-- Honda
`-- Yellow
|-- BMW (notice this doesn't appear twice under 'yellow', like in the second tree above)
`-- Honda
In SQL, this is like a Star Schema , used in Data Warehouse databases for Online Analytical Processing (OLAP) . 在SQL中,这就像星形模式 ,已在数据仓库数据库中用于在线分析处理(OLAP) 。
In your case, that would be a Fact table Vehicle
and 3 Dimensions ( Type
, Brand
, Color
). 在您的情况下,那将是一个事实表Vehicle
和3个维度( Type
, Brand
, Color
)。
I'd suggest keeping the vehicles in a list, and build the 6 trees/indexes from the list, rather than trying to convert one tree to another. 我建议将车辆保留在列表中,并从列表中构建6棵树/索引,而不是尝试将一棵树转换为另一棵树。
A fully typed implementation might be to define a generic abstract tree: 一个完全类型化的实现可能是定义一个通用抽象树:
public abstract class Tree<F, D1, D2, D3> {
protected Tree(List<F> facts) {
// code here using getDimensionN() to build tree
}
protected abstract D1 getDimension1(F fact);
protected abstract D2 getDimension2(F fact);
protected abstract D3 getDimension3(F fact);
public List<F> get(D1 dimension1) {
// code here
}
public List<F> get(D1 dimension1, D2 dimension2) {
// code here
}
public List<F> get(D1 dimension1, D2 dimension2, D3 dimension3) {
// code here
}
// other public accessor methods here
}
You can then construct a particular tree using code like: 然后,您可以使用以下代码来构建特定的树:
List<F> facts = ...;
Tree<Vehicle, Type, Brand, Color> typeBrandColorTree = new Tree<Vehicle, Type, Brand, Color>(facts) {
protected Type getDimension1(Vehicle vehicle) { return vehicle.getType(); }
protected Brand getDimension2(Vehicle vehicle) { return vehicle.getBrand(); }
protected Color getDimension3(Vehicle vehicle) { return vehicle.getColor(); }
};
// Use of tree
List<Vehicle> audiCars = typeBrandColorTree.get(Type.CAR, Brand.AUDI);
Update 更新资料
The Star Schema may not be appropriate for your particular question, so this is more for information about Star Schemas. 星型模式可能不适用于您的特定问题,因此更多有关星型模式的信息。 Let me use an example to illustrate what a Fact might be. 让我用一个例子来说明事实。
A fact could be the sale of a Vehicle, where the sale statistics being tracked includes: 一个事实可能是车辆的销售,其中跟踪的销售统计信息包括:
The trees/indexes can then be used to answer questions like: 然后,树/索引可用于回答以下问题:
For faster access, the tree nodes could even have pre-aggregated values like Count
and TotalPrice
, such that you won't need to iterate all the facts to get your answers. 为了更快地访问,树节点甚至可以具有预先聚合的值,例如Count
和TotalPrice
,这样您就不需要遍历所有事实来获得答案。
This is mainly used for huge data sets (eg 10 years of national sales data), to help managers get various summary statistics on-demand, fast. 这主要用于大型数据集(如10周年全国的销售数据),以帮助管理者获得点播各种汇总统计,快捷。 Hence the term "Online Analytical Processing". 因此,术语“在线分析处理”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.