【问题标题】:Read from .csv and display the items like in the example in Java从 .csv 读取并显示类似 Java 示例中的项目
【发布时间】:2020-06-13 07:46:05
【问题描述】:

即使从这项任务开始,我也遇到了一些问题,所以我认为你们中的一些人可能会有所帮助。基本上,我得到了一个 .csv 文件,如下例所示,它应该像示例输出一样显示。

这是 .csv 文件的内容:

第一个是 ID,第二个 menuname,第三个是父 ID(如果它是一个数字,它应该是那个数字的孩子),如果 Hidden 为 true,它不应该显示。

ID;MenuName;ParentID;isHidden;LinkURL
1;Company;NULL;False;/company
2;About Us;1;False;/company/aboutus
3;Mission;1;False;/company/mission
4;Team;2;False;/company/aboutus/team
5;Client 2;10;False;/references/client2
6;Client 1;10;False;/references/client1
7;Client 4;10;True;/references/client4
8;Client 5;10;True;/references/client5
10;References;NULL;False;/references

这是输出:

. Company 
.... About Us 
....... Team 
.... Mission 
. References 
.... Client 1 
.... Client 2
  • 菜单项应根据它们所属的父项缩进。
  • 有些项目已隐藏,不应显示
  • 项目应按字母顺序排列

你们能告诉我如何开始以及使用什么数据结构(我想到的是 Stack),但我不确定。谢谢!

这是我目前的代码。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Stack;


public class Main {

    static void Function() {


    }

    public static void main(String[] args) throws IOException {
    // write your code here

        BufferedReader csvReader = new BufferedReader(new FileReader("Navigation.csv"));
        String row;
        int parent_id = 0;
        Stack stack = new Stack();

        while ((row = csvReader.readLine()) != null) {
            String[] data = row.split(";");
            stack.push(row);


            for(int i=0; i<4; i++){
                System.out.print(data[i] + " ");
                if(data[2].equals("NULL")){
                    parent_id = Integer.parseInt(data[0]);
                }
            }
            System.out.println(parent_id);

        }
        csvReader.close();


        for(int i=0;i<10;i++){
            System.out.println(stack.pop());
        }
    }
}

【问题讨论】:

  • 好的,你从一个 Class 和一个静态 main 方法开始。告诉我们你在哪里卡住了。
  • 您好,您可能想要使用树形结构,实际上如图所示here - 您在LinkUrl 列中有类似的路径结构
  • 不,我没那么卡哈哈。我已经设法阅读了 cvs 文件和所有内容,但我不知道如何从逻辑角度解决问题。我在上面添加了我的代码。顺便说一句,我尝试了几件事,这并不一定意味着什么。

标签: java csv


【解决方案1】:

要在 java 中解析 CSV,您可以使用第三方库,例如 Apache Commons。它提供了一种通过 Headers 获取的机制。

作为存储它的数据结构,您可以使用Map,其中Key为int(假设ID为int),Value为POJO,其类结构如下:

   class MenuItem {
    Node node;
    List<Node> childNodes;
}

Node定义为:

   class Node {
    String menuName;
    Boolean isHidden;
    String url;
    }

对于根节点,childNodes 将是 null

注意:解决方案的后半部分基于您的节点只能是一层深的假设(根据提供的示例)。

【讨论】:

    【解决方案2】:

    这是你可以做的:

    1. 定义一个类Item(可以使用Node

      class Item {
       int id;
       String name;
       int parentId;
       String link;
       boolean hidden;
       List<Item> children;
      }
      
    2. 阅读 CSV 并创建项目列表 Item(我们正在分别执行第 2 步和第 3 步,因为在您的 CSV 中父项目是随机顺序的)

      List<Item> items = new ArrayList<Item>();
      items.add(new Item(id, name, parentId, link, hidden)); // get these values from CSV, set parentId as `0` if it is null
      
      items = items.stream().sorted((a, b) -> a.parentId - b.parentId)).collect(Collectors.toList()); // sort item by ascending order of parentId
      
    3. 创建一个具有层次结构的新列表

      List<Item> treeHireachy  = new ArrayList<Item>();
      // iterate through the previous list and add only first level items to this list.
      // then add remaining items as child nodes/item to based on the appropriate parent item
      

    【讨论】:

      【解决方案3】:

      使用单个项目集合来做到这一点有点困难。

      您不仅需要为每个项目 (id --&gt; MenuItem) 进行映射,还需要通过 MenuNameMenuItems 进行排序的方法。最重要的是,您需要维护层次结构的树形结构。

      我建议两个集合:Map&lt;Integer, MenuItem&gt;SortedSet&lt;MenuItem&gt;。为了构建层次结构树,循环遍历集合并将子级添加到它们的父级,直到您只剩下根 MenuItems - 没有父级的那些。

      实际的打印应该足够清晰——你递归地打印MenuItems 的所有子树。

      这是我的解决方案。这就是你的运行方式:java MenuItems &lt; "your_csv_file"

      import java.util.HashMap;
      import java.util.HashSet;
      import java.util.Map;
      import java.util.Scanner;
      import java.util.Set;
      import java.util.SortedSet;
      import java.util.TreeSet;
      
      public class MenuItems {
          public static void main(String[] args) {
              Scanner sc = new Scanner(System.in);
      
              // skip the header line
              sc.nextLine();
      
              // Read all menu items
              SortedSet<MenuItem> menuItemsSet = new TreeSet<MenuItem>();
              Map<Integer, MenuItem> menuItemsMap = new HashMap<Integer, MenuItem>();
              while (sc.hasNextLine()) {            
                  MenuItem nextItem = new MenuItem(sc.nextLine().split(";"));
                  menuItemsSet.add(nextItem);
                  menuItemsMap.put(nextItem.id, nextItem);
              }
      
              // build tree structure
              Set<MenuItem> reunitedChildren = new HashSet<MenuItem>();
              for (MenuItem nextItem : menuItemsSet) {
                  // if an item has a parent
                  if (nextItem.parentId != -1) {
                      menuItemsMap.get(nextItem.parentId).addChild(nextItem);
                      reunitedChildren.add(nextItem);
                  }
              }
              menuItemsSet.removeAll(reunitedChildren);
      
              // print result:
              printMenu(" ", menuItemsSet);
          }
      
          private static void printMenu(String indent, SortedSet<MenuItem> subtree) {
              for (MenuItem nextItem : subtree) {
                  if (!nextItem.isHidden) {
                      System.out.println(indent + " " + nextItem.menuName);
                      if (!nextItem.children.isEmpty()) {
                          printMenu(indent + "   ", nextItem.children);
                      }
                  }
              }
          }
      }
      
      class MenuItem implements Comparable<MenuItem> {
          int id;
          String menuName;
          int parentId;
          boolean isHidden;
          String linkUrl;
      
          SortedSet<MenuItem> children;
      
          public MenuItem(String[] fields) {
              this(
                  Integer.parseInt(fields[0]),
                  fields[1],
                  fields[2].equals("NULL") ? -1 : Integer.parseInt(fields[2]),
                  Boolean.parseBoolean(fields[3]),
                  fields[4]
              );
          }
      
          public MenuItem(
              int id,
              String menuName,
              int parentId,
              boolean isHidden,
              String linkUrl
          ) {
              this.id = id;
              this.menuName = menuName;
              this.parentId = parentId;
              this.isHidden = isHidden;
              this.linkUrl = linkUrl;
              this.children = new TreeSet<MenuItem>();
          }
      
          public void addChild(MenuItem child) {
              this.children.add(child);
          }
      
          @Override
          public boolean equals(Object obj) {
              MenuItem that = (MenuItem) obj;
              return this.id == that.id;
          }
      
          @Override
          public int hashCode() {
              return this.id;
          }
      
          @Override
          public int compareTo(MenuItem that) {
              return this.menuName.compareTo(that.menuName);
          }
      }
      

      【讨论】:

      • 你要先编译程序:javac MenuItems.java
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      相关资源
      最近更新 更多