Эффективный код для сохранения данных в ArrayList - PullRequest
0 голосов
/ 26 апреля 2020

Моя консоль выводит теги года из файла XML, подобного этому

2020
2019
1997
2017
2019
2017 (...)

Из этих данных, которые я хочу сохранять каждый год в ArrayList, например:

Years found on file: 2020 , 2019 , 1997 , 2017

Я много чего перепробовал, но ни одна из них, похоже, не работает. Я пытаюсь найти решение с помощью следующего кода:

public class Publications {
    public static void main(String[] args) throws IOException {
        File file = new File("dblp-2020-04-01.xml");
        FileInputStream fileStream = new FileInputStream(file);
        InputStreamReader input = new InputStreamReader(fileStream);
        BufferedReader reader = new BufferedReader(input);
        String line;
        ArrayList<String> publicationsList = new ArrayList<String>();
        int i = 0;
        while ((line = reader.readLine()) != null) {
            Publications publ = new Publications();
            Pattern pattern = Pattern.compile("<year>(.+?)</year>", Pattern.DOTALL);
            Matcher matcher = pattern.matcher(line);
            if (matcher.find()) {
                String year = matcher.group(1);
                if (publicationsList.size() == 0) {
                    publicationsList.add(year);
                }else{
                    for(String publications1 : publicationsList){
                        if(!(publications1.contains(year))){
                            publicationsList.add(year);
                        }
                    }
                }
            }
        }
        //READING TEST
        for (String publications1 : publicationsList){
            System.out.println(publications1);
        }
    }
}

Ошибки:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)
    at Publications.main(Publications.java:26)

1 Ответ

1 голос
/ 26 апреля 2020

Замените ArrayList на LinkedHashSet, и дубликаты будут автоматически игнорироваться, при этом порядок вставленных значений все еще сохраняется.

Кроме того, это год 2020, поэтому вам следует использовать API-интерфейс NIO.2 и оператор try-with-resources, оба из которых были добавлены в Java 7 еще в 2011 году. Это поможет решить проблему, если вы не закроете поток файлов.

Вот как должен выглядеть ваш код:

Set<String> publicationYears = new LinkedHashSet<>();
try (BufferedReader reader = Files.newBufferedReader(Paths.get("dblp-2020-04-01.xml"))) {
    Pattern pattern = Pattern.compile("<year>(.+?)</year>", Pattern.DOTALL);
    for (String line; (line = reader.readLine()) != null; ) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            String year = matcher.group(1);
            publicationYears.add(year);
        }
    }
}
//READING TEST
for (String year : publicationYears){
    System.out.println(year);
}

Конечно, поскольку вы читаете файл XML, было бы гораздо лучше использовать XML parser , например StAX:

Set<String> publicationYears = new LinkedHashSet<>();
try (InputStream in = Files.newInputStream(Paths.get("dblp-2020-04-01.xml"))) {
    XMLStreamReader xml = XMLInputFactory.newFactory().createXMLStreamReader(in);
    while (xml.hasNext()) {
        xml.next();
        if (xml.getEventType() == XMLStreamConstants.START_ELEMENT) {
            if (xml.getLocalName().equals("year")) {
                String year = xml.getElementText();
                publicationYears.add(year);
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...