【发布时间】:2019-08-03 09:45:18
【问题描述】:
我需要编写需要 2 个集合的算法,List<String> 和 MyClass[]
public class MyClass {
String key;
String value;
}
然后它将遍历MyClass[] 并检查它的key 是否也在List<String> 中。这里不能简单contains,key有2部分,文本和数字(例如“Lorem ipsum 1990”,我们只需要检查文本部分所以这里有trimNumber方法。
public String trimNumber(String key) {
String[] splitKey = key.split(" ");
return splitKey [splitKey .length-1].matches(("\\d+(\\.\\d+)?")) ?
key.replace(splitKey [splitKey .length-1], "").trim() : key;
}
现在,我需要计算这场比赛的每一次出现。 最后一步,是从整个集合中找到最高出现率。
最后,我的实现
public long calculate(final List<String> list, final MyClass[] data) {
return Arrays.stream(data)
.map(MyClass::getKey)
.map(Main::trimNumber)
.filter(list::contains)
.collect(Collectors.groupingBy(v -> v, Collectors.counting()))
.values()
.stream()
.mapToLong(i -> i)
.max()
.orElse(1);
}
现在的问题是,我可以简化它吗?或者改变一些东西让性能更好?那部分只是更大算法的一部分,它将对大量数据进行操作。假设每个 HTTP 请求 15 000 x MyClass[150]。所以每一秒都很重要。
【问题讨论】:
-
List.contains() 是 O(N)。首先将其转换为 HashSet。 HashSet.contains() 是 O(1)。
-
用
return key.replaceFirst(" ?+\\d+(\\.\\d+)?$", "");替换你的trimNumber实现,它已经在使用正则表达式,当没有匹配时它已经返回原始字符串,并且通过前置" ?+"和附加$,它将如果有空格,则限制为最后一个以空格分隔的术语。不需要split。
标签: java performance java-stream