我得到了一系列元素,如:
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;
}
答案 0 :(得分:2)
很多调整,但我终于明白了!
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);
}
请注意,我必须从路径中删除初始/
,否则该字符将在拆分中使用,导致每个路径列表中的第一个字符串为空字符串,这将始终是最常见的前缀。但是,在预处理中不应该太难做到这一点。