Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 排序数组列表<;字符串>;合并起始处具有相同名称的行的步骤_Java - Fatal编程技术网

Java 排序数组列表<;字符串>;合并起始处具有相同名称的行的步骤

Java 排序数组列表<;字符串>;合并起始处具有相同名称的行的步骤,java,Java,我正在解析pdf时间表以创建JSON文件,我在arrayList中的文本文档中有alle字符串。我想用相同的停止名连接文本文档中的行。Java中是否有任何帮助类可以做到这一点 简单: amsterdam street 04:41 05:41 06:09 06:38 07:08 07:38 08:08 08:38 09:08 09:38 10:08 10:38 11:08 11:38 paris 04:43 05:43 06:11 06:41 07:11 07:41 08:11 08:41 09

我正在解析pdf时间表以创建JSON文件,我在arrayList中的文本文档中有alle字符串。我想用相同的停止名连接文本文档中的行。Java中是否有任何帮助类可以做到这一点

简单:

amsterdam street 04:41 05:41 06:09 06:38 07:08 07:38 08:08 08:38 09:08 09:38 10:08 10:38 11:08 11:38
paris  04:43 05:43 06:11 06:41 07:11 07:41 08:11 08:41 09:11 09:41 10:11 10:41 11:11 11:41
rom  04:48 05:48 06:16 06:46 07:16 07:46 08:16 08:46 09:16 09:46 10:16 10:46 11:16 11:46
amsterdam street 12:08 12:38 13:08 13:38 14:08 14:38 15:08 15:38 16:08 16:38 17:08 17:38 18:08 18:38
paris  12:11 12:41 13:11 13:41 14:11 14:41 15:11 15:41 16:11 16:41 17:11 17:41 18:11 18:41
rom  12:16 12:46 13:16 13:46 14:16 14:46 15:16 15:46 16:16 16:46 17:16 17:46 18:16 18:46

因此,在
ArrayList
中有所有行,并且需要将以相同两个单词开头的行连接起来。我会首先拆分空格字符,然后合并以相同内容开头的行。在这种情况下,我喜欢使用
Map
s,因为它很容易保持组织性

Pattern pattern = Pattern.compile("(.*?)\\s*((?:\\s\\d{2}:\\d{2})+)");

// A map will keep us organized, because it disallows duplicate keys
Map<String, StringBuilder > times = new HashMap<>(); // Map<header, times>
for (String line : LINES_IN_FILE) {
    // Separate the times from the header and each other
    Matcher match = pattern.matcher(line);

    // Use the first capturing group as the key and the second as the value
    times.get(match.group(1)).append(match.group(2));
}

// now for some post-processing
ArrayList<String> result = new ArrayList<>(times.keySet().size());
for (String key : times.keySet()) {
    result.add(key + " " + times.get(key);
}
return result;
Pattern=Pattern.compile((*?)\\s*((?:\\s\\d{2}:\\d{2})+);
//地图将使我们保持有序,因为它不允许重复的密钥
映射时间=新建HashMap();//地图
for(字符串行:文件中的行){
//将时间与页眉分开,并彼此分开
匹配器匹配=模式匹配器(线);
//使用第一个捕获组作为键,第二个作为值
get(match.group(1)).append(match.group(2));
}
//现在进行一些后处理
ArrayList结果=新的ArrayList(times.keySet().size());
for(字符串键:times.keySet()){
结果.add(key+“”+times.get(key);
}
返回结果;

为了实现这一点,我们必须做出一些假设,因为没有安全的分隔符。因此,我们必须找到分割头部的最有力的指标。看起来一行总是以
hh24:mm
格式的时间结尾。我们可以使用以下信息:

private static final Pattern pattern = 
    Pattern.compile("^ *(.+?)((?: +(?:[01][0-9]|2[0-3]):[0-5][0-9])+) *$");

public static final void splitLine(String line) {
    Matcher matcher = pattern.matcher(line);
    if (matcher.find()) {
        System.out.println("stop: " + matcher.group(1));
        System.out.println("times: " + matcher.group(2));
        // the time string will have the space(s) at the beginning, so it can be
        // concatenated without problem, but the first space might have to be trimmed
    }
}
(已测试)合并不再太困难(未测试):

//splitLine()的自适应,只需遍历所有行,就可以
//映射中的所有内容,您可以在条目集上进行迭代。
专用void addLine(字符串行、映射站){
匹配器匹配器=模式匹配器(线);
if(matcher.find()){
if(stops.containsKey(matcher.group(1))){
stops.put(matcher.group(1),stops.get(matcher.group(1))+matcher.group(2));
}否则{
stops.put(matcher.group(1)、matcher.group(2.trim());
}
}
}

如果站点名称不完全是两个单词,您的拆分将失败。在示例中,始终是这样,因此可能向OP提问:您的站点名称是否总是以空格分隔的两个单词?我假设是这样,因为我没有理由相信会是这样。当然,如果是这样,问题会简化。否则,我可能会使用reg用于区分时间格式字符串和普通字符串的正则表达式。@Grmpfhmbl是的,你是对的,停止名称并不总是两个单词。@gobernador为我的错误感到抱歉,因此我更喜欢使用正则表达式而不是split()。例如(.*)s+(\d\d:\d\d)+第一个捕获组将是您的站点,后者将为您提供时间我正在尝试进行合并,但当我声明映射并添加以下内容时,请将这两行替换为`times.get(matcher.group(1)).append(matcher.group(2));`I在线程“main”中收到此错误
异常java.lang.NullPointerException
您能将合并代码添加到您的答案中以测试它吗?@MrPencil现在检查它。在解析ArrayList的方法中声明并初始化它,使用HashMap。它是一个映射(当然是两个字符串),但我没有收到另一个错误
方法hasKey(字符串)未定义类型映射
?在
hasKey,按
lines?containsKey
// adaptation of splitLine(), just iterate through all lines, then you will have
// everything in the map and you can iterate over the entry sets.
private void addLine(String line, Map<String, String> stops) {
    Matcher matcher = pattern.matcher(line);
    if (matcher.find()) {
        if (stops.containsKey(matcher.group(1))) {
            stops.put(matcher.group(1), stops.get(matcher.group(1)) + matcher.group(2));
        } else {
            stops.put(matcher.group(1), matcher.group(2).trim());
        }
    }
}