我有一个输入数组
["Setra","Mercedes","Volvo","Mercedes","Skoda","Iveco","MAN",null,"Skoda","Iveco"]
预期输出应为
{Iveco=2, Mercedes=2, Skoda=2, MAN=1, Setra=1, Volvo=1}
含义是一个地图,其钥匙为Vehicle品牌,值作为其出现次数,且类似的值元素应按字母顺序和值按钥匙排序。
我尝试过
public static String busRanking(List<String> busModels) {
Map<String, Long> counters = busModels.stream().skip(1).filter(Objects::nonNull)
.filter(bus -> !bus.startsWith("V"))
.collect(Collectors.groupingBy(bus-> bus, Collectors.counting()));
Map<String, Long> finalMap = new LinkedHashMap<>();
counters.entrySet().stream()
.sorted(Map.Entry.comparingByValue(
Comparator.reverseOrder()))
.forEachOrdered(
e -> finalMap.put(e.getKey(),
e.getValue()));
return finalMap.toString();
}
public static void main(String[] args) {
List<String> busModels = Arrays.asList( "Setra","Mercedes","Volvo","Mercedes","Skoda","Iveco","MAN",null,"Skoda","Iveco");
String busRanking = busRanking(busModels);
System.out.println(busRanking);
}
我得到的输出
{Skoda=2, Mercedes=2, Iveco=2, Setra=1, MAN=1}
有什么建议吗?而且必须使用单个stream()获得输出
答案 0 :(得分:1)
我认为最好的解决办法是:
public static void main(String... args) {
List<String> busModels = Arrays.asList( "Setra","Mercedes","Volvo","Mercedes","Skoda","Iveco","MAN",null,"Skoda","Iveco");
Map<String, Long> collect = busModels.stream()
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
TreeMap<String, Long> stringLongTreeMap = new TreeMap<>(collect);
Set<Map.Entry<String, Long>> entries = stringLongTreeMap.entrySet();
ArrayList<Map.Entry<String, Long>> list = new ArrayList<>(entries);
list.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));
String busRanking = list.toString();
System.out.println(busRanking);
}
答案 1 :(得分:1)
如果您可以使用第三方库,则可以在带有Eclipse Collections的流中使用它:
function cc(card) {
// Only change code below this line
if (card==2 || card==3 || card==4 || card==5 || card==6) {
count+=1;
}
else if (card==7 || card==8 || card==9) {
count+=0;
}
else if (card==10 || card=="J" || card=="Q" || card=="K" || card=="A") {
count-=1;
}
else {
return "No such combination";
}
if (count>0) {
return count + " " + "Bet";
}
else {
return count + " " + "Hold";
}
// Only change code above this line
}
// Add/remove calls to test your function.
// Note: Only the last will display
cc(7); cc(8); cc(9);
输出:
Comparator<ObjectIntPair<String>> comparator =
Comparators.fromFunctions(each -> -each.getTwo(), ObjectIntPair::getOne);
String[] strings = {"Setra", "Mercedes", "Volvo", "Mercedes", "Skoda", "Iveco",
"MAN", null, "Skoda", "Iveco"};
List<ObjectIntPair<String>> pairs = Stream.of(strings).collect(Collectors2.toBag())
.select(Predicates.notNull())
.collectWithOccurrences(PrimitiveTuples::pair, Lists.mutable.empty())
.sortThis(comparator);
System.out.println(pairs);
这也可以通过不使用Streams来稍微简化。
[Iveco:2, Mercedes:2, Skoda:2, MAN:1, Setra:1, Volvo:1]
注意:我是Eclipse Collections的提交者
答案 2 :(得分:0)
Map<String, Long> map = busModels.stream()
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.sorted(Comparator
.comparing((Entry<String, Long> e) -> e.getValue()).reversed()
.thenComparing(e -> e.getKey()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (left, right) -> left + right, LinkedHashMap::new));
发生了什么事
LinkedHashMap
中,以保留插入顺序。输出:
{Iveco=2, Mercedes=2, Skoda=2, MAN=1, Setra=1, Volvo=1}
这使用单个方法链接语句。但是,我不会将其称为单个流操作,因为实际上创建了两个流,一个用于收集出现的流,另一个用于设置排序项的新流。
通常,流的设计至少要在标准Java API中进行一次。
存在一个名为StreamEx的库,该库可能包含允许我们通过单个流操作来完成此操作的方法。
Map<String, Long> map = StreamEx.of(buses)
.filter(Objects::nonNull)
.map(t -> new AbstractMap.SimpleEntry<>(t, 1L))
.sorted(Comparator.comparing(Map.Entry::getKey))
.collapse(Objects::equals, (left, right) -> new AbstractMap.SimpleEntry<>(left.getKey(), left.getValue() + right.getValue()))
.sorted(Comparator
.comparing((Entry<String, Long> e) -> e.getValue()).reversed()
.thenComparing(e -> e.getKey()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (left, right) -> left + right, LinkedHashMap::new));
发生了什么事
Entry
的流中,每个键是总线名称,每个值是出现的初始次数,即1
。collapse
方法,该方法使用合并功能合并满足给定谓词的相邻元素的系列。因此Mercedes => 1 + Mercedes => 1
成为Mercedes => 2
。这似乎至少是在单个流操作中完成的。