2017-01-31 1 views
0

У меня есть карта, которая была отсортирована по алфавиту, преобразуя ее с помощью TreeMap. Карта содержит как String (имя файла установщика), так и Path (путь установщика в файловой системе), например Установщики карт;Получение последнего аналогичного объекта из карты в Java

Мне нужно получить самое последнее имя файла установщика. Однако регулярное выражение кажется слишком сложным.

Код я в настоящее время, чтобы отобразить монтажников и их пути заключается в следующем:

Map<String, Path> installers = findInstallers(); 
    Set s = installers.entrySet(); 
    Iterator it = s.iterator(); 
    while(it.hasNext()) { 
     Map.Entry entry = (Map.Entry) it.next(); 
     String installerFile = (String) entry.getKey(); 
     Path installerPath = (Path) entry.getValue(); 
     System.out.println(installerFile + " ==> " + installerPath.toString()); 
    } 
    System.out.println("================================"); 

private Map<String, Path> findInstallers() { 

    HashMap<String, Path> installerPathMap = new HashMap<>(); 
    try { 
     Path productReleasePath = Paths.get("C:", "test"); 
     List<Path> allPaths = Files.walk(productReleasePath) 
       .filter(Files::isRegularFile) 
       .collect(Collectors.toList()); 

     allPaths.forEach(path -> { 
      if (!path.toFile().getName().toLowerCase().endsWith(".log")) { 
       String installerFiileName = path.toFile().getName(); 
       installerPathMap.put(installerFiileName, path); 
      } 
     }); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return new TreeMap<>(installerPathMap); 
} 

Это пример вывода:

Client_1.exe ==> C:\test\build_1\Win32\Client_1.exe 
Client_5.exe ==> C:\test\build_5\Win32\Client_5.exe 
Client_6.exe ==> C:\test\build_6\Win32\Client_6.exe 
Server_1.exe ==> C:\test\build_1\Win64\Server_1.exe 
Server_2.exe ==> C:\test\build_2\Win64\Server_2.exe 
Server_Linux_1.tar.gz ==> C:\test\build_1\Linux32\Server_Linux_1.tar.gz 
Server_Linux_2.tar.gz ==> C:\test\build_2\Linux32\Server_Linux_1.tar.gz 
================================ 

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

Client_6.exe ==> C:\test\build_6\Win32\Client_6.exe 
Server_2.exe ==> C:\test\build_2\Win64\Server_2.exe 
Server_Linux_2.tar.gz ==> C:\test\build_2\Linux32\Server_Linux_1.tar.gz 
================================ 

Любая помощь будет большой я оценил.

ответ

0

Если вы добавили пути к карте, используя корень имени установщика в качестве ключа (т. Е. Часть перед подчеркиванием) и отбросьте самую низкую версию при столкновении с ключом, вы получите то, что хотите ,

Обратите внимание, что сортировка названий в алфавитном порядке не будет работать, потому что версия 9 будет сортироваться после 10, поэтому вам нужно будет извлечь версию и выполнить цифровое сравнение.

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

public class InstallerList { 

    public static void main(String[] args) throws IOException { 
     Path productReleasePath = Paths.get("C:", "test"); 

     Collection<Path> installers = Files.walk(productReleasePath) 
      .filter(Files::isRegularFile) 
      .filter(p -> !p.getFileName().toString().endsWith(".log")) 
      // Collect files with the highest version 
      .collect(Collectors.toMap(
       // Key is installer name *without* version 
       InstallerList::extractName, 
       // Value mapper; identity mapping to the path 
       p -> p, 
       // Select newest version when there is a collision 
       InstallerList::newer 
      )) 
      .values(); 

     for (Path path : installers) { 
      System.out.println(path.getFileName() + " ==> " + path); 
     } 
    } 

    // Extract the root name of an installer from a path (up to but not including the last '_') 
    public static String extractName(Path path) { 
     String fileName = path.getFileName().toString(); 
     int i = fileName.lastIndexOf('_'); 
     if (i < 0) { 
      throw new IllegalArgumentException(fileName); 
     } 
     return fileName.substring(0, i); 
    } 

    // Return the path with the highest version number 
    public static Path newer(Path p1, Path p2) { 
     return extractVersion(p1) > extractVersion(p2) ? p1 : p2; 
    } 

    // Extract a version number from a path (number between the last '_' and the following '.') 
    private static int extractVersion(Path path) { 
     String fileName = path.getFileName().toString(); 
     int i = fileName.lastIndexOf('_'); 
     if (i < 0) { 
      throw new IllegalArgumentException(fileName); 
     } 
     int j = fileName.indexOf('.', i); 
     if (j < 0) { 
      throw new IllegalArgumentException(fileName); 
     } 
     return Integer.parseInt(fileName.substring(i + 1, j)); 
    } 
} 
+0

К сожалению, для имен файлов установки не существует стандартного соглашения об именах. У некоторых есть тире в названии, у других - подчеркивания, но это должно быть хорошей отправной точкой. У других есть полный номер версии, а только номер сборки. Например: 'code' WebAgent-1.2.3.zip Спасибо за помощь! – user7497643

Смежные вопросы