我必须使用Streams API从给定文件中查找所有最长的单词。我只做了几步,但寻找一些“一行”,实际上我处理整个文件两次,第一次是找到单词的最大长度,第二次是比较所有单词和最大长度,假设它不是性能最好的;有人能帮我吗?看看代码:
public class Test {
public static void main(String[] args) throws IOException {
List<String> words = Files.readAllLines(Paths.get("alice.txt"));
OptionalInt longestWordLength = words.stream().mapToInt(String::length).max();
Map<Integer, List<String>> groupedByLength = words.stream().collect(Collectors.groupingBy(String::length));
List<String> result = groupedByLength.get(longestWordLength.getAsInt());
}
}
我想澄清一下:
List<String> words = Files.readAllLines(Paths.get("alice.txt"));
List<String> result = // code
文件每行只包含一个单词,无论如何这并不重要——问题是关于正确的流代码。
迭代映射键以查找最长的字长
减少
将帮助您:
Optional<String> longest = words.stream()
.reduce((s1, s2) -> {
if (s1.length() > s2.length())
return s1;
else
return s2;
});
如果流
为空,它将返回一个可选值。空的
如果你想要最大长度的所有单词的列表,这篇文章将帮助你:
Optional<List<String>> longest = words.stream()
.collect(Collectors.groupingBy(
String::length,
Collectors.toList()
))
.entrySet()
.stream()
.reduce(
(entry1, entry2) -> {
if (entry1.getKey() > entry2.getKey())
return entry1;
else
return entry2;
}
)
.map(Map.Entry::getValue);
你可以将单词从它们的长度收集到单词的地图中,然后取最长的一个:
List<String> longestWords =
Files.lines(Paths.get("alice.txt"))
.collect(Collectors.groupingBy(String::length))
.entrySet()
.stream()
.sorted(Map.Entry.<Integer, List<String>> comparingByKey().reversed())
.map(Map.Entry::getValue)
.findFirst()
.orElse(null);
编辑:
正如Malte Hartwig所指出的,在流地图上使用max
更优雅(可能更快):
List<String> longestWords =
Files.lines(Paths.get("alice.txt"))
.collect(Collectors.groupingBy(String::length))
.entrySet()
.stream()
.max(Map.Entry.comparingByKey())
.map(Map.Entry::getValue)
.orElse(null);
EDIT2:
上述两种解决方案都存在内在的低效性,因为它们都构建了一个映射,基本上存储了文件中所有字符串的长度,而不仅仅是最长的字符串。如果在您的用例中,性能比优雅更重要,您可以编写自己的收集器
,只保留列表中最长的字符串:
private static int stringInListLength(List<String> list) {
return list.stream().map(String::length).findFirst().orElse(0);
}
List<String> longestWords =
Files.lines(Paths.get("alice.txt"))
.collect(Collector.of(
LinkedList::new,
(List<String> list, String string) -> {
int stringLen = string.length();
int listStringLen = stringInListLength(list);
if (stringLen > listStringLen) {
list.clear();
}
if (stringLen >= listStringLen) {
list.add(string);
}
},
(list1, list2) -> {
int list1StringLen = stringInListLength(list1);
int list2StringLen = stringInListLength(list2);
if (list1StringLen > list2StringLen) {
return list1;
}
if (list2StringLen > list1StringLen) {
return list2;
}
list1.addAll(list2);
return list1;
}
));
问题内容: 我正在使用PostgreSQL,并且在表中有一列,其中包含非常长的文本。我想在查询中选择此列,但限制其显示长度。 就像是: 我该怎么做? 问题答案: 您可以做的是使用PostgreSQL的substring()方法。以下两个命令之一将起作用:
问题内容: 我试图从表中获取所有列的列表,这些列表包含它们的数据类型,数据长度和该列中最长值的长度。 我使用此SQL来获取列及其数据类型和长度: 我有此SQL,用于获取值的最大长度: 但是我不知道如何将它们结合起来。我正在使用SQL Server 2008。 问题答案: 感谢您的建议。我想出了以下解决方案。它为我获取了我需要的数据,但是希望了解它是否可以提高效率。
我有这个问题: 您将获得一个整数 A 和一个整数 k 的数组。您可以将 A 的元素递减到 k 次,目标是生成一个元素都相等的连续子数组。返回可以用这种方式生成的最长的连续子数组的长度。 例如,如果 A 是 [1,7,3,4,6,5] 并且 k 是 6,那么您可以生成 [1,7,3,4-1,6-1-1-1,5-1-1] = [1,7,3,3,3,3],因此您将返回 4。 最佳解决方案是什么?
我已经用RowSelectionModel和RowSelectionProvider创建了一个NatTable: 基本上,表做我想让它做的事情。只有一个例外: 该表如下所示: 所以,我现在有点卡住了。是什么导致标头单元格被突出显示,我如何改变这种行为?是否可以只突出光标单元格的标头(就像对选定行的光标单元格(2)所做的那样)?
我正在制作一个JavaFX应用程序,在启动时,TextField有默认文本,上面写着“请输入这个值”,用户应该删除该文本并输入一个值。但是,每次单击、拖动和高亮显示所有文本是相当痛苦的。当用户单击文本字段时,是否有一种方法可以自动突出显示所有文本以便于删除,但只有当文本等于默认消息时才可以?我研究了这个,没有找到任何东西,任何帮助都是非常感谢的。
可能这是一个幼稚的问题,但我是初学者请不要认为是错误的问题。我搜索了很多,也跟着这个 http://developer.android.com/guide/topics/ui/notifiers/notifications.html教程。还有谷歌解决我的问题,但我找不到。 这是我的作业。 我在主活动中有一个EditText和一个按钮,当我单击该按钮时生成一个通知,当我打开该通知时另一个活动打开,显