#java
#Ява
Вопрос:
Допустим, у меня есть список имен файлов с разными расширениями:
ArrayListlt;Stringgt; list = Arrays.asList("filename1.txt", "filename2.txt", "filename2.xml", "filename2.csv", "filename3");
и я хотел бы проверить (в идеале также подсчитать вхождения), существует ли определенное имя файла независимо от расширения.
Поэтому я хотел бы проверить filename2
, существует ли он в списке. Если я использую Collections.frequency
или contains()
это работает только с полным именем.
Есть какие-нибудь идеи?
Комментарии:
1. Не из коробки. У тебя есть
String
список. Java не знает, что это имена файлов. Вам нужно будет определить логику для анализа имен файлов. Это, в свою очередь, может потребовать учета файловой системы (в некоторых файловых системах, «foo.txt» и «FOO.TXT» одинаковы, на других нет). Тогда что такое расширение? Это.gz
внутриfile.tar.gz
или нет.tar.gz
? О чемreport.internal.december.txt
? Лучше всего пройтись по списку, проанализировать имена файлов, а затем выполнить проверку по мере необходимости.2. Я бы создал карту с измененными именами файлов. Добавьте элемент, если он не существует, иначе он уже существует. Ключом будет имя, я не вижу, какое вам дело до значения, поэтому оставьте его таким же, как и ключ.
Ответ №1:
Одна из идей состоит в том, чтобы использовать хэш-картуlt;Строка, списокgt;.
Ключами будут имена файлов, а значениями-различные расширения.
Поэтому вы бы проверили map.containsKey(«имя файла 2»). Если вам нужны полные имена файлов, вы бы объединили ключ со всеми возможными расширениями в списке значений (т. Е. .txt,.xml и т. Д.)
Комментарии:
1. Пожалуйста, добавьте в этот ответ какой-нибудь конкретный код, чтобы лучше его объяснить
Ответ №2:
Вы можете сделать это, повторяя список и вызывая contains()
каждый String
.
на каждой итерации, если значение contains()
возвращает значение true, вы можете увеличить счетчик.
Или вы также можете использовать регулярное выражение для сопоставления шаблона вместо contains()
метода и выполнить еще более точное сопоставление.
Например: для имени abc.txt
файла , если вы ищете имя tx
файла с помощью contains, вы получите истинное возвращаемое значение.
Вы можете справиться с этими сценариями, используя сопоставление шаблонов регулярных выражений.
Ответ №3:
public static void main(String[] args) { Listlt;Stringgt; list = Arrays.asList("filename1.txt", "filename2.txt", "filename2.xml", "filename2.csv", "filename3.txt"); System.out.println(mapToExtension(list)); } public static Maplt;String,Listlt;Stringgt;gt; mapToExtension(Listlt;Stringgt; list){ Maplt;String,Listlt;Stringgt;gt; extensionMap = new HashMaplt;gt;(); for (String filename: list){ String[] dotSeparator = filename.split("\."); // Assuming last dot separator is the extension String ext = dotSeparator[dotSeparator.length-1]; if (!extensionMap.containsKey(ext)){ extensionMap.put(ext,new ArrayListlt;gt;()); } Listlt;Stringgt; sameExtensionList = extensionMap.get(ext); // Add it to the list sameExtensionList.add(filename); } return extensionMap; }
Как только вы получите карту , вы всегда сможете проверить существующие расширения с помощью карты.
Ответ №4:
Если вы используете Java 8 или более позднюю версию, вы можете использовать Stream API:
Listlt;Stringgt; list = Arrays.asList("filename1.txt", "filename2.txt", "filename2.xml", "filename2.csv", "filename3.txt"); Listlt;Stringgt; list2 = list.stream() .filter(x -gt; x.indexOf("filename2") gt;= 0) .collect(Collectors.toList()); list2.forEach(str -gt; System.out.println(str " ")); System.out.println("nfound " list2.size() " occurrences");
Этот код будет работать для любой строки, которую вы хотите найти в List
элементах, просто замените строку "filename2"
строкой, которую вы хотите найти.
Надеюсь, это поможет.
Ответ №5:
Вы можете достичь этого многими способами:
- Если вы не используете Java 8 -gt; gt;для циклов
- Если вы используете Java 8 -gt; лямбда-выражение, которое выдает результат в одной строке кода.
ПРИМЕЧАНИЕ: код был успешно протестирован в соответствии с требованиями (дополнительную информацию см. в комментариях).
import java.util.Arrays; import java.util.List; public class Program { public static void main(String[] args) { Listlt;Stringgt; myList = Arrays.asList("filename1.txt", "filename2.txt", "filename2.xml", "filename2.csv", "filename3", ""); String fileName = "filename2"; long countWithoutLambda = getCountWithoutLambdaExpression(myList, fileName); long countWithLambda = getCountWitLambdaExpression(myList, fileName); } // Method to get filename Without Extension public static String getBaseName(String fileName) { int index = fileName.lastIndexOf('.'); return (index == -1) ? fileName : fileName.substring(0, index); } // if you don't use java 8 and want a simple loop public static long getCountWithoutLambdaExpression(Listlt;Stringgt; myList, String fileName) { long filesCount = 0; for (String str : myList) if (getBaseName(str).contains(fileName)) filesCount ; return filesCount; } // if you use Java 8 you can achieve it by using lamda expression public static long getCountWitLambdaExpression(Listlt;Stringgt; myList, String fileName) { return myList.stream().filter(p -gt; getBaseName(p).contains(fileName)).count(); } }