从文件读入arraylist然后将数组列表分成多个字符串,以便我可以单独解析它们

时间:2018-04-08 01:16:47

标签: java string file parsing arraylist

因此,对于我的部分工作,我必须从Java之外的文件中提取信息。我已经完成了那部分。问题是我不确定如何将文件中的字符串实际放入可用于下一部分的变量或循环中。在下面的代码中,我需要用outfile中的单数行替换那些带有Item = Tomato ...的代码部分。我不知道该怎么做。我主要担心的是确保每行都没有硬编码,我猜它会涉及以某种方式或形式循环每一行。任何帮助都会很棒。

我最初是如何添加硬编码的项目,而不是我想要做的是从outfile输入它们:

    list.add(new Item("Ketchup", 1.00, 10, 2.00, itemType.FOOD));
    list.add(new Item("Mayo", 2.00, 20, 3.0, itemType.FOOD));
    list.add(new Item("Bleach", 3.00, 30, 4.00, itemType.CLEANING));
    list.add(new Item("Lysol", 4.00, 40, 5.00, itemType.CLEANING));

代码

    Scanner s = new Scanner(new File("inventory.out"));

    ArrayList<String> inventoryList = new ArrayList<String>();

    while (s.hasNext()){
        inventoryList.add(s.next());
    }
    s.close();

    System.out.println(inventoryList);

    String item = "Tomato,30,1.25,6.50";// input String like the one you would read from a file

    String delims = "[,]"; //delimiter - a comma is used to separate your tokens (name, qty,cost, price)

    String[] tokens = item.split(delims); // split it into tokens and place in a 2D array.

    for (int i=0; i < 4; i++) {
        System.out.println(tokens[i]); // print the tokens.
    }

    String name = tokens[0]; System.out.println(name);

    int qty = Integer.parseInt(tokens[1]);System.out.println(qty);

    double cost = Double.parseDouble(tokens[2]);System.out.println(cost); 

控制台输出:

[Ketchup,1.00,10,2.00,itemType.FOOD,Mayo,2.00,20,3.00,itemType.FOOD,Bleach,3.00,30,4.00,itemType.CLEANING,Lysol,4.00,40,5.00,itemType。清洁]

outfile的内容:

Ketchup,1.00,10,2.00,itemType.FOOD
Mayo,2.00,20,3.00,itemType.FOOD
Bleach,3.00,30,4.00,itemType.CLEANING
Lysol,4.00,40,5.00,itemType.CLEANING

3 个答案:

答案 0 :(得分:1)

你需要有一个明确的策略。

您的输入由行组成,而行又由字段组成。您(据推测)您的目标是将数据处理为&#34;记录&#34;。您可以通过以下几种方式实现:

  1. 使用扫描仪读取行,并将每行拆分/扫描/标记为记录字段。
  2. 将整个输入流扫描为一系列令牌或值,并即时重新组合记录。
  3. 任何一种方法都可行。但是你需要决定你将采取哪种方法......并坚持这种方法。

    (如果您只是在没有明确策略的情况下开始编写或复制代码,您可能会陷入混乱,或者您不理解的代码,或两者兼而有之。)

答案 1 :(得分:0)

尝试删除String item = "Tomato,30,1.25,6.50";,然后用inventoryList.get(thepositionatwhichyouwanttogetanitemfrom);

替换所有&#39;项目

答案 2 :(得分:0)

实施

public int[] xcord = {74,177,288,27,132,479,144,408,19,80,264,380,406,491,18,85,165,206,296,106,49,25,13,78,89,145,138,167,221,234,245,371,449,347,299,379,440,291,462,393,282,338,448,318,398,456};
public int[] ycord = {11,26,41,58,54,71,99,83,121,152,124,113,129,152,214,227,187,206,191,262,276,343,472,407,447,336,458,416,470,334,270,182,185,227,294,276,302,379,356,402,438,417,427,481,475,480};

public void makeActors(){
    for(int x=0;x<46;x++){
        for(int y=0;y<46;y++){
            Box box = new Box();
            addObject(box,xcord[x],ycord[y]);
        }
    }
}

说明

public static void main(String[] args) throws IOException { Path path = Paths.getPath("inventory.out"); List<Item> items = readItems(path); for (Item item : items) { System.out.printf("Item (name='%s', capacity=%d, cost=%f, price=%f)\n", item.getName(), item.getCapacity(), item.getCost(), item.getPrice()); } } public class Item { private final String name; private final int quantity; private final double cost; private final double price; public Item (String name, int capacity, double cost, double price) { this.name = name; this.capacity = capacity; this.cost = cost; this.price = price; } // Getters omitted. } public class ItemUtils { /** * Read all lines from a file and maps them to items. * * @param path the path to the file, non-null * @return the list of items read from the file * @throws IOException if an I/O error occurs reading from the file or a malformed or unmappable byte sequence is read * @throws CustomRuntimeException if a line can't be mapped to an item */ public static List<Item> readItems(Path path) throws IOException { Objects.requireNonNull(path); return Files.readAllLines(path, StandardCharsets.UTF_8) .stream() .map(ItemUtils::mapStringToItem) .collect(Collectors.toList()); } /** * Maps a string to an item. * * @param str the string to map, non-null * @return the mapped item * @throws CustomRuntimeException if the string can't be mapped to an item */ private static Item mapStringToItem(String str) { String[] tokens = str.split(","); if (tokens.length != 4) { String msg = String.format("Invalid item: 4 tokens expected, %d tokens found", tokens.length); throw new CustomRuntimeException(msg); } try { String name = tokens[0]; int quantity = Integer.parseInt(tokens[1]); double cost = Double.parseDouble(tokens[2]); double price = Double.parseDouble(tokens[3]); return new Item(name, quantity, cost, price); } catch (NumberFormatException e) { throw new CustomRuntimeException("Invalid item: Type conversion failed", e); } } private ItemUtils() { // Utility class, prevent instantiation. } } /** * A custom runtime exception. Should be renamed to a more specific name. */ public class CustomRuntimeException extends RuntimeException { public CustomRuntimeException(String msg) { super(msg); } public CustomRuntimeException(String msg, Throwable e) { super(msg, e); } 方法使用Files.readAllLines(...)将所有行读入字符串列表,其中每个字符串对应一行。然后我使用Java 8 Stream API处理此列表的字符串,列表类提供stream()方法返回readLines

  

如果要对集合对象执行某些操作   示例:过滤,排序或操作其上的每个元素   基于某些条件的对象,可以使用java 8流特性   用更少的代码轻松完成您的要求。

Here你可以找到更实用的溪流解释。

流的map(...)方法将Stream<String>的方法引用作为其参数。当您查看mapStringToItem的签名时,您会看到它将一个字符串作为参数并返回mapStringToItem个对象。因此,您可以阅读Item调用&#34;使用方法.map(...)&#34;将文件中的每一行映射到项目。然后,我从流中收集所有项目,并使用collect(...)方法将它们放入新列表中。

让我们看一下mapStringToItem方法,它使用您的方法分割项目值:首先,我们在每个mapStringToItem分割一行,返回一个数组字符串。目前,项目类包含4个应该读取的属性:名称,容量,成本和价格。因此,我们检查字符串数组是否具有适当的长度,如果不是,则此实现会引发异常。如果我们有4个字符串(split {by ,),我们可以开始将字符串值解析为适当的数据类型,如果类型转换失败则抛出异常。最后但并非最不重要的是,我们返回一个带有解析值的项目。

评论

请注意,我建议不要使用浮点变量来存储货币值。看看Joda-Money

可能值得搜索处理数据类序列化的库。如果您不介意将格式更改为JSON jackson-databind,或者类似的库可以作为解决方案。