#java #string #arraylist
#java #строка #список массивов
Вопрос:
У меня есть программа обработки файлов.
В нем у меня есть метод, который проверяет имя файла (строку) на ArrayList
соответствие имен файлов. Идея в том, что программе не нужно обрабатывать файлы, которые ArrayList
уже находятся в.
Проблема, с которой я сталкиваюсь, заключается в том, что ArrayList
может быть очень большим (16 000 элементов), и я перебираю примерно одинаковое количество файлов, так что проверка каждого файла на ArrayList
соответствие занимает слишком много времени. Я думаю, это потому, что я использую .contains
.
Существует ли более эффективный (т. Е. Более Быстрый) способ выполнения этих строк для ArrayList
сравнения с очень большими списками массивов или я должен хранить в другой структуре данных?
Мой код:
public class Iterator {
static ArrayList<String> myFiles = new ArrayList<String>();
static String filename= "/Files/FilesLogged.txt";
public static void main(String[] args) throws IOException, SAXException, TikaException, SQLException, ParseException, URISyntaxException, BackingStoreException {
BufferedReader reader = new BufferedReader(new InputStreamReader(ClassLoader.class.getResourceAsStream(filename)),2048);
String line = null;
while((line = reader.readLine()) != null) {
myFiles.add(line);
}
reader.close();
}
public static void loopthrough(String folderName) throws IOException, SAXException, TikaException, SQLException, ParseException, URISyntaxException{
System.out.println("This is the loopthrough folderName" folderName);
File dir = new File(folderName);
File[] directoryListing = dir.listFiles();
if (directoryListing != null) {
for (File child : directoryListing) {
if(!myFiles.contains(child.getName())){
System.out.println("THE FILE NAMES ARE" child.getName().toString());
}
}
}
Комментарии:
1. Пожалуйста, правильно отформатируйте свой код. Прямо сейчас это нечитаемо.
2. Почему бы вместо этого не использовать HashSet?
3. Быстрее ли хэш-набор?
Ответ №1:
Вы должны использовать Set (HashSet или TreeSet).
Эти структуры данных позволяют вам проверять существование элемента в нем за время O (1) или O (log n) соответственно.
ArrayList сравнивает значение с каждым элементом, поэтому оно равно O(n).
Я бы рекомендовал вам использовать HashSet. Накладные расходы на его использование составляют около ~ 70 байт для каждой записи.
Комментарии:
1. HashSet поддерживает метод contains . Значит, я все еще могу использовать этот метод и получать более быстрые сравнения?
2. @SebastianZeki, да. Хотя метод имеет то же имя и проверяет, сохранен ли элемент, он работает совершенно по-другому под капотом и работает намного быстрее.
3. Хорошо, спасибо. Это здорово.
Ответ №2:
Прежде всего, вы должны использовать алгоритм поиска. Простым началом будет бинарный поиск. Это даст вам время обработки на lg (n) меньше n. (Например, 10 шагов вместо 1024);
Если список массивов меняется не так часто, вы можете выполнить этот поиск в любое время, используя другой поток (если у вас есть информация или время, чтобы сделать это раньше). И после того, как вы нашли результат, вы можете его кэшировать, вы будете удалять кеш, если список массивов изменился