Есть ли в java способ проверить, является ли строка частью многих строк в списке

#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:

Вы можете достичь этого многими способами:

  1. Если вы не используете Java 8 -gt; gt;для циклов
  2. Если вы используете 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();  } }