Java 使用streams返回字母所在字符串的总和
我有一个单词列表(编程语言),我想找出字母表中的哪个字母出现在这些单词中,然后将这些单词的字符串总长度相加,最后返回一个字母,返回与这些单词匹配的最长字符串。这是我到目前为止得到的,我几乎没有进一步的进展 这是我试图更好地理解java流的一个练习Java 使用streams返回字母所在字符串的总和,java,java-stream,Java,Java Stream,我有一个单词列表(编程语言),我想找出字母表中的哪个字母出现在这些单词中,然后将这些单词的字符串总长度相加,最后返回一个字母,返回与这些单词匹配的最长字符串。这是我到目前为止得到的,我几乎没有进一步的进展 这是我试图更好地理解java流的一个练习 package com.example; import org.junit.Test; import java.util.ArrayList; import java.util.List; import java.util.function.Supp
package com.example;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class DemoApplicationTests {
@Test
public void argh() {
List<String> list = new ArrayList<>();
list.add("java");
list.add("php");
list.add("python");
list.add("perl");
list.add("c");
list.add("lisp");
list.add("c#");
Supplier<Stream<String>> streamSupplier = () -> list.stream();
IntStream.range('a', 'z').forEach(i -> {
int strlen = streamSupplier.get()
.filter(k -> {
char ch = (char) i;
return k.contains("" + ch);
}
)
.map(s -> s.length())
.mapToInt(Integer::new)
.sum();
System.out.println((char) i + " : " + strlen);
}
);
}
}
我不得不稍微修改和优化你的代码。最终解决办法将是:
Map.Entry<Integer, Integer> max = IntStream.range('a', 'z').boxed().collect(Collectors.toMap(i -> i, i -> list.stream()
.filter(k -> k.contains("" + (char) i.intValue()))
.map(String::length)
.mapToInt(Integer::new)
.sum()))
.entrySet().stream()
.max((e1, e2) -> e1.getValue().compareTo(e2.getValue())).get();
System.out.println((char)max.getKey().intValue() + ":" + max.getValue());
Map.Entry max=IntStream.range('a','z').boxed().collect(Collectors.toMap(i->i,i->list.stream)()
.filter(k->k.contains(“+(char)i.intValue()))
.map(字符串::长度)
.mapToInt(整数::新)
.sum())
.entrySet().stream()
.max((e1,e2)->e1.getValue().compareTo(e2.getValue()).get();
System.out.println((char)max.getKey().intValue()+“:”+max.getValue());
变化如下:
1) 将IntStream
转换为Stream
,以便能够从中收集地图
2) 收集对:符号的int值->具有此符号的单词总和
并且至少3)找到包含最大元素的地图条目您非常接近,基本上只是缺少了流的顺序 为了使整个订购过程更加简单,您可以创建一个专用类:
class CharacterLengthSumResult implements Comparable<CharacterLengthSumResult> {
final char c;
final int sum;
CharacterLengthSumResult(char c, int sum) {
this.c = c;
this.sum = sum;
}
@Override
public int compareTo(CharacterLengthSumResult o) {
return Integer.compare(o.sum, sum);
}
}
你期望得到什么样的结果?你能描述一下这个具体例子的结果吗?你想做什么还不太清楚。我觉得不错,你有什么问题吗?也许这更适合CodeReview?我不想要所有的,我只想要最长的。最好是在地图上或类似的地方。我只是想用stream()-api来表达我的想法,并试图通过一些奇怪的例子来表达我的想法,以便更好地理解。@Holger:谢谢,我现在看到了!陛下看起来像overcomplicated@Andremoniyhm看起来像是干净的代码,而不是黑客攻击地图条目。黑客攻击地图条目???:)哈哈哈,你在哪里看到黑客?如果您不知道如何烹饪流,这并不意味着它是“黑客”:)很抱歉,根据IntelliJ的说法,显然我可以做到:“.max(Comparator.comparating(Map.Entry::getValue)).get();”谢谢!如果您关心性能,可以将
.filter(k->k.contains(“+(char)i.intValue())
替换为.filter(k->k.indexOf(i)>=0)
和.map(String::length).mapToInt(Integer::new)
替换为.mapToInt(String::length)
。请注意,更有效的替代方案甚至更简单。和.max((e1,e2)->e1.getValue().compareTo(e2.getValue())
可以简化为.max(Map.Entry.comparingByValue())
。
Map.Entry<Integer, Integer> max = IntStream.range('a', 'z').boxed().collect(Collectors.toMap(i -> i, i -> list.stream()
.filter(k -> k.contains("" + (char) i.intValue()))
.map(String::length)
.mapToInt(Integer::new)
.sum()))
.entrySet().stream()
.max((e1, e2) -> e1.getValue().compareTo(e2.getValue())).get();
System.out.println((char)max.getKey().intValue() + ":" + max.getValue());
class CharacterLengthSumResult implements Comparable<CharacterLengthSumResult> {
final char c;
final int sum;
CharacterLengthSumResult(char c, int sum) {
this.c = c;
this.sum = sum;
}
@Override
public int compareTo(CharacterLengthSumResult o) {
return Integer.compare(o.sum, sum);
}
}
Optional<CharacterLengthSumResult> first = IntStream.range('a', 'z').mapToObj(i -> {
String c = ((char) i) + "";
int sum = list.stream().filter(s -> s.contains(c)).mapToInt(String::length).sum();
return new CharacterLengthSumResult((char)i, sum);
}).sorted().findFirst();
if (first.isPresent()) {
System.out.println(first.get().c + " -> " + first.get().sum);
}
...sorted().collect(Collectors.toMap(s -> s.c, s -> s.sum));