有没有办法窥视流中的下一个元素?这个想法来自一个对象列表的流,其中应该比较两个跟随的对象(以平滑一些差异,但这在这里不重要).作为一个旧for循环,这看起来像:
List<Car> autobahn = getCars();
for (int i = 0; i < autobahn.size()-1; i++) {
if(autobahn.get(i).speed>autobahn.get(i+1).speed)
autobahn.get(i).honk();
}
Run Code Online (Sandbox Code Playgroud)
到目前为止流的最佳方式是:
autobahn.stream()
.limit(autobahn.size()-1)
.filter(car -> car.speed < autobahn.get(autobahn.indexOf(car)+1).speed)
.forEach(car -> car.honk());
Run Code Online (Sandbox Code Playgroud)
这个解决方案的主要问题是indexOf方法,因为高速公路上可能有两倍于同一辆车.一个更好的解决方案是某种方式来窥视下一个(或前一个)元素(有一个帮助类,这可能是可能的,但看起来很可怕)
BoxedCar boxedCar = new BoxedCar(autobahn.get(0));
autobahn.stream()
.skip(1)
.filter(car -> boxedCar.setContent(car))
.forEach(car -> car.winTheRace());
Run Code Online (Sandbox Code Playgroud)
与助手类
class BoxedCar {
Car content;
BoxedCar(Car content) {
this.content = content;
}
boolean setContent(Car content) {
double speed = this.content.speed;
this.content = content;
return content.speed > speed;
}
}
Run Code Online (Sandbox Code Playgroud)
或者转移Stream<Car>到 …
我有一个整数流,我想找到两个数字,其总和等于另一个数字.所以我想出了以下解决方案:
BiPredicate<Integer, Integer> p = (price1, price2) -> price1.intValue() + price2.intValue() == moneyQty;
flavoursPrices.filter(p);
Run Code Online (Sandbox Code Playgroud)
但是过滤方法没有收到BiPredicate.为什么不?有什么替代方案?
我正在编写一个函数,使用Java 8 Stream将数组转换为Map.
这就是我想要的
public static <K, V> Map<K, V> toMap(Object... entries) {
// Requirements:
// entries must be K1, V1, K2, V2, .... ( even length )
if (entries.length % 2 == 1) {
throw new IllegalArgumentException("Invalid entries");
}
// TODO
Arrays.stream(entries).????
}
Run Code Online (Sandbox Code Playgroud)
有效的用法
Map<String, Integer> map1 = toMap("k1", 1, "k2", 2);
Map<String, String> map2 = toMap("k1", "v1", "k2", "v2", "k3", "v3");
Run Code Online (Sandbox Code Playgroud)
无效的用法
Map<String, Integer> map1 = toMap("k1", 1, "k2", 2, "k3");
Run Code Online (Sandbox Code Playgroud)
有帮助吗?
谢谢!
我想取一串字符串并将其转换为单词对流.例如:
我有: { "A", "Apple", "B", "Banana", "C", "Carrot" }
我想:{ ("A", "Apple"), ("Apple", "B"), ("B", "Banana"), ("Banana", "C") }.
这与使用带有lambda的JDK8的Zipping流中概述的Zipping几乎相同(java.util.stream.Streams.zip)
但是,这会产生:
{ (A, Apple), (B, Banana), (C, Carrot) }
以下代码有效,但显然是错误的方法(不是线程安全等):
static String buffered = null;
static void output(String s) {
String result = null;
if (buffered != null) {
result = buffered + "," + s;
} else {
result = null;
}
buffered = s;
System.out.println(result);
}
// *****
Stream<String> testing …Run Code Online (Sandbox Code Playgroud) 是否存在用于通过排序元素的成对迭代的Java习惯用法Collection?我的意思是每次迭代都可以访问集合的一个元素和集合的下一个元素?
对于排序的Lists(和数组),可以使用集合中的索引来完成:
final int n = list.size();
assert 2 <= n;
for (int i = 0; i < n - 1; ++i) {
final Thing thing1 = list.get(i);
final Thing thing2 = list.get(i+1);
operateOnAdjacentPair(thing1, thing2);
}
Run Code Online (Sandbox Code Playgroud)
但那怎么样SortedSet?(因为SortedMap你可以使用它entrySet(),这相当于SortedSet案例).
因此,例如,如果您的有序集包含值{1,2,3,4},则迭代将按对象(1,2),(2,3),(3,4)的顺序进行.
我有一个对象列表,如下所示:
{
value=500
category="GROCERY"
},
{
value=300
category="GROCERY"
},
{
value=100
category="FUEL"
},
{
value=300
category="SMALL APPLIANCE REPAIR"
},
{
value=200
category="FUEL"
}
Run Code Online (Sandbox Code Playgroud)
我想将其转换为如下所示的对象列表:
{
value=800
category="GROCERY"
},
{
value=300
category="FUEL"
},
{
value=300
category="SMALL APPLIANCE REPAIR"
}
Run Code Online (Sandbox Code Playgroud)
基本上将所有值添加到同一类别.
我应该使用flatMap吗?降低?我不明白这些的细微差别来弄明白.
救命?
编辑:
这个问题有一些密切的重复: Java 8 api流中是否有一个aggregateBy方法? 和 Stream API的对象的Sum和属性
但在这两种情况下,最终结果都是地图,而不是列表
根据@AndrewTobilko和@JBNizet的回答,我使用的最终解决方案是:
List<MyClass> myClassList = list.stream()
.collect(Collectors.groupingBy(YourClass::getCategory,
Collectors.summingInt(YourClass::getValue)))
.entrySet().stream().map(e -> new MyClass(e.getKey(), e.getValue()).collect(toList());
Run Code Online (Sandbox Code Playgroud) 在获得Java 8流程的过程中,以下练习阻止了我.
鉴于
IntStream.range(0, 6).生成以下字符串流:Run Code Online (Sandbox Code Playgroud)"0, 1" "1, 2" "2, 3" "3, 4" "4, 5"
我想使用Collectors.collectAndThen将它传递给好的旧列表或数组并循环以构造字符串列表,如下所示:
List<String> strgs = new ArrayList<>();
String prev = String.valueOf(nums[0]);
for (int i = 1; i < nums.length; i++) {
strgs.add(prev+", "+String.valueOf(nums[i]));
prev = String.valueOf(nums[i]);
}
Run Code Online (Sandbox Code Playgroud)
但它没有使用流的力量.我觉得Venkat Subramaniam说"我之后想洗个澡".我想知道如何应用功能技术,所以我可以在编码后跳过洗澡!
另外,我想避免像StreamEx或JavaRx这样的库,我想坚持使用普通的Java 8 API.
编辑:@Tunaki,谢谢你在我的问题中指出不清楚的措辞.它是由Stream的两个连续元素组成的对.更具体的,像小溪[1, 3, 5, 7, 9, ...]会
"1, 3"
"3, 5"
"5, 7"
...
Run Code Online (Sandbox Code Playgroud)
编辑2
在向所有答案致敬之后,虽然我的问题与Tunaki指出的另一个问题重复.我想扩展一个社区讨论,以寻找Bohemian提供的答案.虽然他的回答不被一些人所厌恶,但它提出了一个严重的问题,即减少手术的副作用.我向社区提出的要求是为该问题提供合理的反有效技术.因此我想重用波希米亚的答案如下:
给定输入:nums = new int [] {1,3,5,7,9}
请考虑以下代码段:
List<CharSequence> stringList = new ArrayList<>();
IntBinaryOperator reductionWithSideEffect …Run Code Online (Sandbox Code Playgroud) 注意:我不一定在寻找下面描述的具体示例问题的解决方案.我真的很感兴趣为什么在Java 8中不可能开箱即用.
Java流是懒惰的.最后他们有一个终端操作.
我的解释是这个终端操作将通过流提取所有值.没有任何中间操作可以做到这一点.为什么没有中间操作通过流引入任意数量的元素?像这样的东西:
stream
.mapMultiple(this::consumeMultipleElements) // or groupAndMap or combine or intermediateCollect or reverseFlatMap
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
当下游操作尝试使流一次前进时,中间操作可能尝试多次上行(或根本不上行).
我会看到几个用例:(
这些只是示例.所以你可以看到它确实可以处理这些用例,但它不是"流式传输方式",而且这些解决方案缺乏Streams所具有的理想的懒惰属性. )
将多个元素组合到一个新元素中,以传递到流的其余部分.(例如,成对(1,2,3,4,5,6) ? ((1,2),(3,4),(5,6)))
// Something like this,
// without needing to consume the entire stream upfront,
// and also more generic. (The combiner should decide for itself how many elements to consume/combine per resulting element. Maybe the combiner is a Consumer<Iterator<E>> or a Consumer<Supplier<E>>)
public <E, R> Stream<R> combine(Stream<E> stream, BiFunction<E, E, R> combiner) {
List<E> completeList …Run Code Online (Sandbox Code Playgroud)有没有一种很好的方法将字符串列表(使用Collectos API?)转换/转换为HashMap?
StringList和Map:
List<String> entries = new ArrayList<>();
HashMap<String, String> map = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
...
我的StringList包含如下字符串:
entries.add("id1");
entries.add("name1, district");
entries.add("id2");
entries.add("name2, city");
entries.add("id3");
entries.add("name3");
Run Code Online (Sandbox Code Playgroud)
输出应该是:
{id1=name1, district, id2=name2, city, id3=name3}
Run Code Online (Sandbox Code Playgroud)
谢谢!
作为学习Java 8+ Streams的练习,我想将一些简单的Codility实现转换为Stream解决方案。
例如,BinaryGap问题..使用Streams的一个简单的线性解决方案可能类似于:
public static int solution(int N) {
return Integer.toBinaryString(N).chars().
filter(x -> x == 1).whichIndexes().diff().max();
}
Run Code Online (Sandbox Code Playgroud)
唯一的问题是,虽然,whichIndexes并且diff不存在。我需要一种方法来获取已过滤元素的索引,然后计算它们的成对差异,这将是基于Streams的单线解决方案的良好起点。
更新:这是我的C ++ BinaryGap解决方案,但是Java非Stream-ed版本将非常相似:
#include <bitset>
#include <iostream>
#include <math.h>
using namespace std;
int solution(int N) {
bitset<32> bs(N);
int maxGap = 0;
std::size_t i = 0;
while (bs[i] == 0) {
i++;
}
int startPos = i;
for (; i < bs.size(); ++i) {
if (bs[i] == 1) {
int gap = i - startPos …Run Code Online (Sandbox Code Playgroud) 例如,是否可以将字符str.chars()流转换为字符串流,其中每个字符串包含 5 个字符?