java数据结构来模拟数据树

时间:2010-11-18 16:06:06

标签: java parsing data-structures map tree

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

<device>
    <manufacturer>Acer</manufacturer>
    <model>A1</model>
    <platform>Android</platform>
</device>
<device>
    <manufacturer>Acer</manufacturer>
    <model>A1</model>
    <platform>J2ME</platform>
</device>
<device>
    <manufacturer>Acer</manufacturer>
    <model>A2</model>
    <platform>Android</platform>
</device>
<device>
    <manufacturer>Samsung</manufacturer>
    <model>E400</model>
    <platform>Android</platform>
</device>

所以,我会有像manufacturer = {“Acer”,“Acer”,“Acer”,“Samsung”},model = {“A1”,“A1”,“A2”,“E400”},平台= { “机器人”, “J2ME”, “机器人”, “机器人”}。

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

3 个答案:

答案 0 :(得分:4)

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

所以,我的建议如下。

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

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

  5. 像这样:

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

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

    manufactuerIndex.get("Nokia") - &gt;返回所有诺基亚设备。

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

答案 1 :(得分:2)

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

这是我的产品对象:

public class Product implements Comparable<Product>{

    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<Product>并对其应用视图。这是一个示例方法,它返回按模型过滤的实时视图:

public static Collection<Product> filterByModel(
    final Collection<Product> products,
    final String model){
    return Collections2.filter(products, new Predicate<Product>(){

        @Override
        public boolean apply(final Product product){
            return product.getModel().equals(model);
        }
    });
}

像这样使用:

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

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

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

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

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

答案 2 :(得分:1)

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

TreeMap<String, TreeMap<String, Model> manufacturerMap;

TreeMap<String, Model> models = manufacturerMap.get( name );
if( models == null ) {
    models = new TreeMap<String, Model>();
    manufacturerMap.put( name. models );
}

... etc ...