【问题标题】:Retrieve String from values in HashMap at a specific occurrence of special character在特殊字符的特定出现处从 HashMap 中的值中检索字符串
【发布时间】:2019-04-02 11:25:32
【问题描述】:

所以我正在尝试在像这样构造的 Hashmap 中检索值中的特定子字符串..

HashMap<ID, "Home > Recipe > Main Dish > Chicken > Chicken Breasts">

这是从返回 HashMap 的不同方法传递的

在上面的例子中,我需要检索鸡。

到目前为止,我已经..

public static ArrayList<String> generalize() {
    HashMap<String, String> items = new HashMap<>();
    ArrayList<String> cats = new ArrayList<>();
    items = RecSys.readInItemProfile("PATH", 0, 1);
    for(String w : items.values()) {
        cats.add(w);
    }

    for(String w : cats) {

        int e = w.indexOf('>', 1 + w.indexOf('>', 1 + w.indexOf('>')));

        String k = w.substring(e+1);

        System.out.print(k);

        e = 0;
    }
    System.out.println("k" + cats);
    return cats;
}

我尝试在每次迭代中使 String e 无效(我知道这是多余的,但只是为了测试)。

在我的数据集中,第一个 k-v 对是

3880=Home  >  Recipes  >  Main Dish  >  Pasta, 

我的输出是

Pasta

没关系。如果超过 3x ">",它将返回以下所有类别。最佳情况下它不会那样做,但如果那样做也没关系。然而,更进一步,它(似乎)随机返回

Home > Recipe

连同其他数据... 我相信这发生在第 6 个循环。

非常感谢任何帮助..

编辑:

为了澄清,我有一个包含 3 列的 .csv 文件,而此函数中使用了 2 列(ID 和类别)。这些通过另一个类中的读取方法传递给此函数。

我需要做的是提取每个类别的概括描述,这在所有情况下都是类别规范的第三个实例(即,总是在每个 kv 对中的第三个和第四个“>”之间)。

我的想法是简单地将所有值放在一个数组列表中,并为每个值从第三个和第四个“>”之间提取一个字符串。

【问题讨论】:

  • 您发布的代码中的HashMap在哪里?
  • 我建议规范化您的数据,并且不要按照您的方式存储字符串。相反,也许让每个 ID 映射到一组字符串。为什么要以这种方式存储您的信息?
  • @TimBiegeleisen 你是对的。我完全忘记包含数据是从读取方法传递的,该方法指定要从 .csv 文件中提取哪些列。在本例中,0 和 1 作为索引(ID 和类别)传递
  • 当你说你需要检索“鸡”时,这究竟是什么意思?如果您在问题中添加更全面的问题陈述,将会有所帮助。
  • @TimBiegeleisen 添加了完整的代码和更好的问题描述。希望它澄清

标签: java split hashmap substring


【解决方案1】:

我建议使用以下地图:

Map<Integer, List> map = new HashMap<>();
String[] vals = new String[] { "HomeRecipe", "Main Dish", "Chicken",
    "Chicken Breasts" };
map.put(1, Arrays.asList(vals));

然后,如果您需要使用ID 在原始字符串中查找给定值,您只需在某个位置调用ArrayList#get()。如果您根本不关心顺序,那么在这里将整数映射到集合可能更有意义。

【讨论】:

    【解决方案2】:

    如果可以的话。将您的数据结构更改为HashMap&lt;Integer, List&lt;String&gt;&gt;HashMap&lt;Integer, String[]&gt;。最好将类别(cats 你的意思是类别对吗?)存储在集合中而不是字符串中。

    那么你就可以轻松拿到第三项了。

    如果这是不可能的。你需要做一些调试。首先打印每个输入和输出对,找出导致意外输出的输入。乍一看,您的 indexOf 方法似乎有效。

    或者,试试这个正则表达式方法:

    String k = cats.replaceAll("(?:[^>]+\\s*>\\s*){3}([^>]+).*", "$1");
    System.out.println(k);
    

    正则表达式基本上会查找xxx &gt; yyy &gt; zzz &gt; aaa ... 模式并将该模式​​替换为aaa(无论原始字符串中的内容)。

    【讨论】:

    • 感谢您的建议。数据是通过哈希图从不同的方法解析的,但是在我的方法中,所有值都被提取并放置在数组列表中。您的正则表达式给了我相同的结果,尽管格式更好。为 Home、Recipe 和 > 添加一个 replaceAll 可以解决我的问题,但我希望有一种“更清洁”的方法。
    • @Sebastian 那么我建议找出究竟是哪些类别导致了意外的字符串k
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 2022-12-22
    相关资源
    最近更新 更多