用于模拟数据树的java数据结构

我需要帮助定义使用的方法。 我有一个SOAP响应给我一个xml文件。 我需要最终在屏幕上显示3个相关列表。 当您在第一个列表中选择一个项目时,相应的选项将出现在第二个列表等上。我只对如何在从xml流中提取数据后有效组织数据感兴趣。 这是一个xml片段:

 Acer A1 Android   Acer A1 J2ME   Acer A2 Android   Samsung E400 Android  

所以,我会有类似manufacturer = {“Acer”,“Acer”,“Acer”,“Samsung”},model = {“A1”,“A1”,“A2”,“E400”},platform = { “机器人”, “J2ME”, “机器人”, “机器人”}。

有趣的是:我需要按摩数据,以便我可以使用它来显示3个列表。 选择Android后,宏碁和三星成为可用的。 如果选择Acer,则可以使用型号A1和A2。 所有列表都需要排序。 目前我正在使用Sax将数据解析为对象向量,包含制造商,模型,平台字段。 我能想到的只是一个类似TreeMap的结构。 任何建议,将不胜感激。

我不认为层次结构是你需要的。 因为用户可以选择第一平台或制造商。 如果他选择第一个Android,则要显示3个设备。 如果他选择第一个宏基,他会看到2个设备。

所以,我的建议如下。

  1. 使用属性制造商,型号,平台创建类设备。
  2. 创建包含所有这些设备的纯链接列表。
  3. 创建2个map:manufaturerIndex和plarformIndex,如下所示:
    Map> manufacturerIndex;

  4. 在列表上迭代一次并填充所有索引映射。

喜欢这个:

 for(Device d : devices) { Collection selected = manufacturerIndex.get(d.getManufacturer()); if (selected == null) { selected = new ArrayList(); manufactuerIndex.put(d.getManufacturer(), selected); } selected.add(d); // the same for the second index } 

现在您可以使用数据结构。

manufactuerIndex.get("Nokia") – >返回所有诺基亚设备。

注意这个数据结构是可扩展的。 您始终可以根据需要添加任意数量的索引。

我只是使用可排序的自定义对象集合,然后根据谓词过滤该集合。 我正在使用Guava来实现这一切,但当然还有其他(通常更复杂的)方法来实现它。

这是我的产品对象:

 public class Product implements Comparable{ private final String manufacturer; private final String model; private final String platform; public Product(final String manufacturer, final String model, final String platform){ this.manufacturer = manufacturer; this.model = model; this.platform = platform; } public String getManufacturer(){ return manufacturer; } public String getModel(){ return model; } public String getPlatform(){ return platform; } @Override public int hashCode(){ return Objects.hashCode(manufacturer, model, platform); } @Override public boolean equals(final Object obj){ if(obj instanceof Product){ final Product other = (Product) obj; return Objects.equal(manufacturer, other.manufacturer) && Objects.equal(model, other.model) && Objects.equal(platform, other.platform); } return false; } @Override public int compareTo(final Product o){ return ComparisonChain .start() .compare(manufacturer, o.manufacturer) .compare(model, o.model) .compare(platform, o.platform) .result(); } } 

现在我只使用TreeSet并对其应用视图。 这是一个示例方法,它返回按模型过滤的实时视图:

 public static Collection filterByModel( final Collection products, final String model){ return Collections2.filter(products, new Predicate(){ @Override public boolean apply(final Product product){ return product.getModel().equals(model); } }); } 

像这样用它:

 Collection products = new TreeSet(); // add some products Collection filtered = filterByModel(products, "A1"); 

更新:我们可以更进一步,只使用一个集合,由链式谓词支持,这些谓词依次绑定到视图支持的模型。 大脑疼吗? 看一下这个:

 // this is the collection you sent to your view final Collection visibleProducts = Collections2.filter(products, Predicates.and(Arrays.asList( new ManufacturerPredicate(yourViewModel), new ModelPredicate(yourViewModel), new PlatformModel(yourViewModel))) ); 

yourViewModel是一个由表单控制器返回的值支持的对象。 每个谓词都使用此模型对象的字段来决定它是否适用。

例如, ModelPredicate检查集合中的所有产品,以查看其模型是否属于所选产品。 由于这是使用and逻辑,您可以使其成为分层结构(如果制造商谓词返回false,则永远不会调用模型和平台谓词)。

我使用嵌套地图做类似的事情。 使用TreeMap获取排序结果:

 TreeMap manufacturerMap; TreeMap models = manufacturerMap.get( name ); if( models == null ) { models = new TreeMap(); manufacturerMap.put( name. models ); } ... etc ...