【问题标题】:Change String in List<String> based on another String same List Java根据另一个 String 相同 List Java 更改 List<String> 中的字符串
【发布时间】:2015-06-30 20:48:08
【问题描述】:

我有一个包含类似字符串的列表:

device0001;sale;2013-01-01 00:00:00;30.45
device0001;sale;2013-01-02 00:00:00;41.02
device0001;sale;2013-01-03 00:00:00;30.45
...
device0001;saleCode;2013-01-01 00:00:00;10
device0001;saleCode;2013-01-02 00:00:00;55
device0001;saleCode;2013-01-03 00:00:00;55

多个设备、多个代码名和设备日期。我想将 saleCode 的 Value 映射到 sale CodeName。 我最后想要的例子:

device0001;10;2013-01-01 00:00:00;30.45
device0001;55;2013-01-02 00:00:00;41.02
device0001;55;2013-01-03 00:00:00;30.45

salesCode 字符串可以保留也可以不保留,没关系。

我已经让它与 2 个 for 循环和 if 一起工作,但处理时间太长了。

我想过构建这样的东西:

Map<String(device), Map<DateTime, Map<String(element), String(value)>>>

forEach device
    forEach datetime
        element (Codename substring) and replace by element (Value substring)

我很确定一定有更好和/或优雅的方法来做到这一点。

编辑 - 因为我似乎不太清楚我为什么要这样做,所以这里是带有 for 和 if 的代码(这太慢了):

    for (String line : lines) {
        if (line.split(SEPARATOR)[4].equals("sale")) {
            for (String codeLine : lines) {
                if (codeLine.split(SEPARATOR)[5].equals(line.split(SEPARATOR)[5]) &&        
                    codeLine.split(SEPARATOR)[1].equals(line.split(SEPARATOR)[1])&& 
                    codeLine.split(SEPARATOR)[4].equals("saleCode")) {

                    line = line.replaceAll("sale", codeLine.split(SEPARATOR)[7]); 
                }
            }
         }
    }

索引不适合我的字符串示例,只是因为还有其他不重要的字段,但索引 [1] 是设备号,[5] 是日期。 [4] 是类型(sale, saleCode),[7] 是值。

编辑#2

我已经像这样提高了速度:

MultiKeyMap<String, String> multiKeyMap = new MultiKeyMap<>();

for (String line : lines) {
    if (line.split(SEPARATOR)[4].equals("saleCode")) {
        String device = line.split(SEPARATOR)[1];
        String date = line.split(SEPARATOR)[5];
        String value = line.split(SEPARATOR)[7];

        multiKeyMap.put(device, date, value);
     }
}

for (int i = 0; i < lines.size(); i++) {
    String code = lines.get(i).split(SEPARATOR)[4];

    if (code.equals("sale")) {
        String device = lines.get(i).split(SEPARATOR)[1];
        String date = lines.get(i).split(SEPARATOR)[5];
        String newline = lines.get(i).replaceAll("sale", multiKeyMap.get(device, date));

        lines.set(i, newline);
     }
}

我会暂时这样做,但总是愿意接受建议。

【问题讨论】:

  • 不使用字符串列表,而是解析为对象列表(每个对象为 4 个字段)。
  • 你只需要读入一个列表,然后写出另一个吗?您是否打算进一步处理它,例如根据 saleCode 做出决定?根据上下文以及您打算如何使用它,您将得到非常不同的答案(对象列表与正则表达式搜索和替换)。
  • @JoD.Yes,只需要读入列表并写入其他。稍后我会进行处理,但它与此映射没有任何关系。

标签: java string list dictionary collections


【解决方案1】:

如果我正确理解您的问题,则您无需构建任何地图等。
您有一个具有该格式的字符串列表。
只需检查每个字符串并使用正则表达式来替换/更新每个字符串。

更新:
您的代码很慢,因为您一遍又一遍地处理每个字符串的列表。

  1. 根据设备 ID 创建哈希图。
  2. 一一检查lines中的字符串。
  3. 检查字符串是否存在于 hashmap 中。
    如果它不存在,则检查它是哪种类型的字符串并应用适当的正则表达式进行替换。将字符串添加到 hashmap
    如果确实存在,则使用新遇到的字符串通过正则表达式更新字符串。
    完成后,哈希图将替换字符串。

注意:我提到正则表达式是因为您似乎有一种特定的格式,并且可以通过这种方式轻松高效地编写它。如果您不能使用正则表达式,例如您不熟悉它们,请按照您正在做的逐个字符解析它的方法。处理一次列表会更好

【讨论】:

  • 不,这不是很清楚,但我认为他确实需要地图。第一个输出字符串从第一个saleCode 字符串中获取10 部分,并从第一个sale 字符串中获取30.45。它匹配这两个输入字符串,因为它们都有2013-01-01 00:00:00。 (我不知道是否可以安全地假设您可以通过将第一个 sale 字符串与第一个 saleCode 字符串匹配,第二个 sale 字符串与第二个 saleCode 字符串等匹配)
  • @DavidKnipe 你是对的,匹配需要同时使用设备号和日期。
猜你喜欢
  • 2012-06-28
  • 2017-05-15
  • 2013-03-30
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 2022-07-31
  • 2010-10-17
相关资源
最近更新 更多