java数据结构模拟数据树

发布于 2024-10-03 04:15:55 字数 1121 浏览 0 评论 0原文

我需要帮助定义使用什么方法。我有一个 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>

所以,我会有类似制造商={"Acer", "Acer", "Acer","Samsung"}, model={"A1","A1", "A2", "E400" },平台={“Android”,“J2ME”,“Android”,“Android”}。

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

I need help defining what approach to use. I have a SOAP response giving me an xml file. I need to end-up with 3 correlated lists displayed on screen. When you select one item on the first list, the corresponding choices will appear on the second list etc. I am only interested on how to organize efficiently the data after it is extracted from the xml stream. Here's an xml snippet:

<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>

So, I will have something like manufacturer={"Acer", "Acer", "Acer","Samsung"}, model={"A1","A1", "A2", "E400"}, platform={"Android","J2ME","Android","Android"}.

Here comes the fun part: I need to massage the data so that I can use it to display 3 lists. After selecting Android, Acer and Samsung become available. If Acer is selected, then model A1 and A2 are available. All lists need to be sorted. Currently I'm using Sax to parse the data into a vector of objects, containing manufacturer, model, platform fields. All I can think of is a TreeMap like structure. Any suggestions would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

喜你已久 2024-10-10 04:15:55

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

所以,我的建议如下。

  1. 创建具有制造商、型号、平台属性的设备类。
  2. 创建一个包含所有这些设备的普通链接列表。
  3. 创建 2 个地图:manufaturerIndex 和 plarformIndex,如下所示:
    地图<字符串,集合<设备>> 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("诺基亚") ->返回所有诺基亚设备。

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

I do not think that hierarchical structure is what you need here. Because user may select first platform or manufacturer. If he selects first Android you want to show 3 devices. If he selects first Acer he will see 2 devices.

So, my suggesting is the following.

  1. create class Device with properties manufacturer, model, platform.
  2. create a plain linked list that contains all these devices.
  3. Create 2 maps: manufaturerIndex and plarformIndex that look like:
    Map<String, Collection<Device>> manufacturerIndex;

  4. Iterate once over the list and populate all indexes maps.

Like this:

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
}

Now you can use the data structure.

manufactuerIndex.get("Nokia") -> returns all Nokia devices.

Pay attention that this data structure is extendable. You can always add as many indexes as you want.

末骤雨初歇 2024-10-10 04:15:55

我只需使用自定义对象的可排序集合,然后根据谓词过滤该集合。我使用 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 并在其上应用视图。下面是一个返回按模型过滤的实时视图的示例方法:

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,则永远不会调用模型和平台谓词)。

I'd just use a sortable collection of custom objects and then filter that collection based on predicates. I am using Guava for all of this, but there are of course other (usually more complicated) ways to implement this.

Here's my Product Object:

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();
    }

}

Now I'd just use a TreeSet<Product> and apply views on it. Here's a sample method that returns a live view that is filtered by model:

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);
        }
    });
}

Use it like this:

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

Update: We can take it even further, using only one collection, backed by chained predicates that are in turn tied to a model backed by your view. Brain hurts? Check this out:

// 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 is an object that is backed by the values returned from your form controller. Each predicate uses a field of this model object to decide whether it applies or not.

e.g. The ModelPredicate checks all products in the collection to see whether their model is among the selected ones. Since this uses and logic, you can make it a hierarchic structure (if the manufacturer predicate returns false, the model and platform predicates are never called).

温柔嚣张 2024-10-10 04:15:55

我使用嵌套地图来实现类似的目的。使用 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 ...

I use nested maps for something like that. Use TreeMap to get sorted results:

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 ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文