【问题标题】:convert a list of package/class names into a parent/children data structure将包/类名称列表转换为父/子数据结构
【发布时间】:2026-02-10 02:10:01
【问题描述】:

我有一个类名列表如下:

   String s1 = "com.mycompany.project.dao.hibernate.BaseDAOHibernate";
    String s2 = "com.mycompany.project.domain.Product";
    String s3 = "com.mycompany.project.domain.ProductCategory";
    String s4 = "com.mycompany.project.service.impl.ProductServiceImpl";
    String s5 = "com.mycompany.project.domain.User";
    String s6 = "com.mycompany.project.service.impl.ProductCategoryServiceImpl";
    String s7 = "com.mycompany.project.dao.hibernate.ProductCategoryDAOHibernate";
    String s8 = "com.mycompany.project.dao.hibernate.ProductDAOHibernate";

    String[] strings = { s1, s2, s3, s4, s5, s6, s7, s8};

我想使用以下类定义将此数组转换为树结构:

public class Item  {
    private String itemName;
    private List<Item> subItems;

}

该方法将获取上面的数组并生成以下对象。

item.ItemName = "com";
item.suItems = {"mycompany"};

item2.itemName = "mycompany";
item2.subItems = {"project");

item3.itemName = {"project"};
item3.subItems = {"dao", "domain", "service"}

...等等。

请告知如何执行此操作,因为我知道我可能有数百个类的列表作为输入。

谢谢

【问题讨论】:

  • 如果你的subItems是List&lt;Item&gt;可能会更好,那么你可以使用递归的方法来添加和搜索
  • 谢谢,编辑了这个问题,我打算把它列出来

标签: java algorithm data-structures collections tree


【解决方案1】:

请看我在 C# 上的实现,对于 Java,您可以将其用作伪代码。

public class Item
{
    private String itemName;
    private List<Item> subItems = new List<Item>();

    public void Push(string[] namespaces, int index)
    {
        if (index >= namespaces.Length)
            return;

        foreach (Item child in subItems)
        {
            if (child.itemName == namespaces[index])
            {
                child.Push(namespaces, index + 1);
                return;
            }
        }

        Item newChild = new Item();
        newChild.itemName = namespaces[index];
        newChild.Push(namespaces, index + 1);
        subItems.Add(newChild);
    }
}

private static void Namespaces()
{
    String s1 = "com.mycompany.project.dao.hibernate.BaseDAOHibernate";
    String s2 = "com.mycompany.project.domain.Product";
    String s3 = "com.mycompany.project.domain.ProductCategory";
    String s4 = "com.mycompany.project.service.impl.ProductServiceImpl";
    String s5 = "com.mycompany.project.domain.User";
    String s6 = "com.mycompany.project.service.impl.ProductCategoryServiceImpl";
    String s7 = "com.mycompany.project.dao.hibernate.ProductCategoryDAOHibernate";
    String s8 = "com.mycompany.project.dao.hibernate.ProductDAOHibernate";

    String[] strings = { s1, s2, s3, s4, s5, s6, s7, s8 };

    Item root = new Item();
    foreach (string s in strings)
    {
        root.Push(s.Split('.'), 0);
    }
    // Do something with root variable.
}

我也推荐使用 HashMap 而不是列表。

【讨论】:

    【解决方案2】:

    这里有一些代码/伪代码可以帮助您使用递归方法:

    public void add(Item node, String name)
    {
        String prefix = the part of the name before the first '.'
        String suffix = the part of the name after the first '.'
        if (there is no suffix)
        {
            subItems.add(new Node(prefix));
        }
        else 
        {
            Item subItem = null;
            if (subItems contains an Item whose itemName is prefix)
            {
                subItem = that item
            }
            else 
            {
                subItem = new Node(prefix);
                subItems.add(subItem);
            }
            add(subItem, suffix);
        }
    }
    

    【讨论】:

    • +1 是一个很好的递归解决方案。我建议使用Map 来加快搜索速度。
    【解决方案3】:

    您可以对每个字符串使用 split() 方法并在所有结果数组上循环:

    for (String s: strings)
    {
        for (String anotherS: s.split(".");
        {
            //assign to itam classes
        }
    }
    

    【讨论】:

      【解决方案4】:

      根据定义,Parent/Child 结构将是某种Tree。考虑以下...

      public class Item  {
         private String itemName;
         private Map<String, Item> subItems;
      }
      
      Map<String, Item> rootMap;
      

      使用其他地方建议的split 方法,然后遍历包中的元素,向下钻取rootMap 的相应分支。

      这是对List 的改进,因为当您有共同的父包时,您必须通过List 进行搜索才能找到合适的Item 以添加新包。

      【讨论】: