Java:使用 Lambda 识别 ArrayList<String> 中的公共(public)路径

标签 java lambda java-8 substring frequency

我有一个元素数组,例如:

ArrayList<String> t = new ArrayList();
t.add("/folder1/sub-folder1");
t.add("/folder2/sub-folder2");
t.add("/folder1/sub-folder1/data");

我需要将输出获取为/folder1/sub-folder1,这主要是重复的路径。

在 python 中,这可以使用以下函数来实现:

   def getRepeatedPath(self, L):
         """ Returns the highest repeated path/string in a provided list """
         try:
             pkgname = max(g(sorted(L)), key=lambda(x, v): (len(list(v)), -L.index(x)))[0]
             return pkgname.replace("/", ".")
         except:
             return "UNKNOWN"

我正在尝试使用 Java 中的等效 lambda 函数。我很震惊,需要一些 lambda 实现方面的帮助。

public String mostRepeatedSubString(ArrayList<String> pathArray) {
   Collections.sort(pathArray);
   String mostRepeatedString = null;
    Map<String,Integer> x = pathArray.stream.map(s->s.split("/")).collect(Collectors.toMap()); 
    return mostRepeatedString;
}

最佳答案

经过很多调整,但我终于明白了!

  public static void main(String[] args) {
    ArrayList<String> t = new ArrayList<String>();
    t.add("folder1/sub-folder1");
    t.add("folder2/sub-folder2");
    t.add("folder1/sub-folder1/data");
    System.out.println(mostRepeatedSubString(t));
  }

  public static String mostRepeatedSubString(List<String> pathArray) {
    return pathArray
      .stream()
      // Split to lists of strings
      .map(s -> Arrays.asList(s.split("/")))
      // Group by first folder
      .collect(Collectors.groupingBy(lst -> lst.get(0)))
      // Find the key with the largest list value
      .entrySet()
      .stream()
      .max((e1, e2) -> e1.getValue().size() - e2.getValue().size())
      // Extract that largest list
      .map(Entry::getValue)
      .orElse(Arrays.asList())
      // Intersect the lists in that list to find maximal matching
      .stream()
      .reduce(YourClassName::commonPrefix)
      // Change back to a string
      .map(lst -> String.join("/", lst))
      .orElse("");
  }

  private static List<String> commonPrefix(List<String> lst1, List<String> lst2) {
    int maxIndex = 0;
    while(maxIndex < Math.min(lst1.size(), lst2.size())&& lst1.get(maxIndex).equals(lst2.get(maxIndex))) {
      maxIndex++;
    }

    return lst1.subList(0, maxIndex);
  }

请注意,我必须从路径中删除初始 / ,否则该字符将在拆分中使用,导致每个路径列表中的第一个字符串为空字符串,这将始终是最常见的前缀。不过,在预处理中做到这一点应该不会太难。

关于Java:使用 Lambda 识别 ArrayList<String> 中的公共(public)路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41272392/

相关文章:

c# - 如何动态创建 lambda 表达式

java - 如何将 List<Obj1> 转换为 Map<Obj1.prop, List<Obj1.otherProp>

java - Spring JMS在同一应用程序中使用点对点和主题

Java CriteriaBuilder Join - 无法解决或不是字段

java - 创建返回 boolean 值的方法数组并迭代 for-each 循环

c# - 如何从带有列表的对象列表创建列表

java - 如何使用 Java 8 在与 ifPresent 相同的条件下返回 orElseThrow?

node.js - 如何在并发 AWS lambda 函数中管理 Postgres 连接?

java - 返回两个可选值的总和,如果至少有一个不存在,则返回 null

java - 在Java8中的可选中抛出异常