繁体   English   中英

java数据结构来模拟数据树

[英]java data-structure to simulate a data 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”},platform = { “机器人”, “J2ME”, “机器人”, “机器人”}。

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

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

所以,我的建议如下。

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

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

像这样:

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") - >返回所有诺基亚设备。

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

我只使用可排序的自定义对象集合,然后根据谓词过滤该集合。 我正在使用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是一个由表单控制器返回的值支持的对象。 每个谓词都使用此模型对象的字段来决定它是否适用。

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

我使用嵌套地图做类似的事情。 使用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 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM