我试图实现一个方法来合并两个Streams中的值基于a Comparator的值.
我有办法做到这一点,我迭代流并将值插入到一个Stream.Builder,但我还没有弄清楚如何制作一个懒惰评估版本(许多流操作的方式),所以它可以处理无限流.
我想要它做的就是对输入数据执行单个合并传递,而不是对流进行排序(实际上,流很可能是无序的;需要保留这种混乱).
static Stream<E> merge(Stream<E> first, Stream<E> second, Comparator<E> c)
Run Code Online (Sandbox Code Playgroud)
我如何懒惰地合并这样的两个流?
如果我用两个Queues作为输入,一些Consumer作为输出,这将是相当简单的:
void merge(Queue<E> first, Queue<E> second, Consumer<E> out, Comparator<E> c){
while(!first.isEmpty() && !second.isEmpty()
if(c.compare(first.peek(), second.peek()) <= 0)
out.accept(first.remove());
else
out.accept(second.remove());
for(E e:first)
out.accept(e);
for(E e:second)
out.accept(e);
}
Run Code Online (Sandbox Code Playgroud)
但我需要使用惰性评估和流来完成这项工作.
为了解决这些评论,这里有一些示例输入和结果:
例1:
merge(
Stream.of(1, 2, 3, 1, 2, 3),
Stream.of(2, 2, 3, 2, 2, 2),
Comparator.naturalOrder()
);
Run Code Online (Sandbox Code Playgroud)
将返回一个将产生此序列的流:
1, 2, 2, 2, 3, 3, 1, 2, …Run Code Online (Sandbox Code Playgroud) 我有一个格式的字符串:
row1col1 row1col2
row2col1 row2col2
row3col1 row3col2
Run Code Online (Sandbox Code Playgroud)
等等...
我想提取每个项目并构建一个具有以下属性的对象数组:
new MyObject(row1col1, row1col2);
Run Code Online (Sandbox Code Playgroud)
我是Java 8和Streams的新手,我想知道如何在没有循环的情况下实现这一点.
通常我会使用a String.split('\n')将行累积到String数组中
然后是一个循环,我将在空格分隔符上再次分割每一行,并使用两个元素的结果数组(row1col1 row1col2)构建我的对象,直到没有更多行要处理.
像这样:
String sausage = "row1col1 row1col2\nrow2col1 row2col2\nrow3col1 row3col2";
String[] rows = sausage.split("\n");
for (String row : rows) {
String[] objectData = u.split("\\s+");
MyObject myObject = new MyObject(objectData[0], objectData[1]);
myObjectList.add(myObject);
}
Run Code Online (Sandbox Code Playgroud)
谁能解释我如何用流来实现同样的目标,那背后的机制是什么让我这样做呢?
在增加元素数量时,这甚至是一种有效的思维方式,因为从我看到的所有示例中,流程都集中在过滤,收集或通常给出一组元素检索应用一些标准的次要集合.
如何在不使用forEach()的情况下调用Stream链中的setter?
List<Foo> newFoos = foos.stream()
.filter(foo -> Foo::isBlue)
.map(foo -> foo.setTitle("Some value")) //I am unable to use this because also changing the data type into Object
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud) 我有一个对象列表,其中每个对象返回List<String>.如何使用Java 8流只获取一个List<String>?
Contact class有以下方法;
public List<String> getSharedFriendsIds() {
return sharedFriendsIds;
}
Run Code Online (Sandbox Code Playgroud)
我有
List<Contact> contactsList;
Run Code Online (Sandbox Code Playgroud)
我在想的是
List<String> sharedContacts = contactsList.stream()
.map(Contact::getSharedFriendsIds)
.sequential()
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
但上面的线不是返回 List<String>,而是 List<List<String>>我不想要的.
调用sequential()和parallel()更改Java 8流管道的执行方式是否放置?
例如,假设我有这样的代码:
new ArrayList().stream().parallel().filter(...).count();
Run Code Online (Sandbox Code Playgroud)
在这个例子中,很明显filter()将并行运行.但是,如果我有这个代码怎么办:
new ArrayList().stream().filter(...).parallel().count();
Run Code Online (Sandbox Code Playgroud)
是否filter()在并行运行仍然还是它按顺序运行?之所以不清楚是因为中间操作filter()是懒惰的,即它们不会在调用终端操作之前运行count().因此,在count()调用时,我们有一个并行流管道但是filter()顺序执行,因为它在调用之前到来了parallel()?
根据一些条件,我从MongoDB读取数据并创建一个List<Document>带结果集.
List<Document> documentList = new ArrayList<Document>();
Run Code Online (Sandbox Code Playgroud)
样本记录看起来像:
documentList: [
Document{
{ _id=5975ff00a213745b5e1a8ed9,
u_id=,
visblty = 1,
c_id=5975ff00a213745b5e1a8ed8,
batchid=null,
pdate=Tue Jul 11 17:52:25 IST 2017,
locale=en_US,
subject = "Document2"
} },
Document{
{ _id=597608aba213742554f537a6,
u_id=,
visblty = 1,
c_id=597608aba213742554f537a3,
batchid=null,
pdate=Fri Jul 28 01:26:22 IST 2017,
locale=en_US,
subject = "Document2"
} }
]
Run Code Online (Sandbox Code Playgroud)
使用此documentList,我再次使用某些条件进行过滤,然后我需要根据某些条件(我将在请求中获取)对过滤器记录进行排序.
List<Document> outList = documentList.stream()
.filter(d -> d.getInteger("visblty") == 1
&& (!StringUtils.isEmpty(req.pdate())? (d.getDate(CommonConstants.PDATE).after(afterDate)): true)
&& (!StringUtils.isEmpty(req.pdate())? (d.getDate(CommonConstants.PDATE).before(beforeDate)): true)
.sorted().skip(4).limit()
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
不确定如何排序(动态需要根据输入更改排序顺序,它看起来像" pdate by DESC"或" subject …
这是一个简单的类,说明了我的问题:
package com.example;
import java.util.function.*;
public class App {
public static void main(String[] args) {
App a1 = new App();
BiFunction<App, Long, Long> f1 = App::m1;
BiFunction<App, Long, Void> f2 = App::m2;
f1.apply(a1, 6L);
f2.apply(a1, 6L);
}
private long m1(long x) {
return x;
}
private void m2(long x) {
}
}
Run Code Online (Sandbox Code Playgroud)
f1,指的是App::m1,和被绑定到a1中f1的来电apply,工作完全正常-编译器是幸福的呼叫可以通过f1.apply就好制成.
f2,指App::m2,不起作用.
我希望能够定义一个没有返回类型的未绑定非静态方法的方法引用,但我似乎无法使其工作.
我有一个将列表转换为地图的功能.调用此函数后,映射的大小不会更改.我正在尝试在以下两个实现之间做出决定:
Map<Long, Object> listToMap(List<Object> objs) {
/* Implementation One: */
Map<Long, Object> map = new HashMap<>(objs.size(), 1);
for (Object obj : objs) {
map.put(obj.getKey(), obj);
}
return map;
/* Implementation Two: */
return objs.stream().collect(Collectors.toMap(Object::getKey, obj -> obj));
}
Run Code Online (Sandbox Code Playgroud)
在第一个实现中,我通过使用1的加载因子和列表的大小为所有元素分配了足够的内存.这确保不会执行调整大小操作.然后,我遍历列表并逐个添加元素.
在第二个实现中,我使用Java 8流来提高可读性.
我的问题是:第二个实现是否会涉及HashMap的多个调整大小,还是已经过优化以分配足够的内存?
我有温度等级
class Temperature {
double minTemp;
double maxTemp;
String city;
String country;
}
Run Code Online (Sandbox Code Playgroud)
我有另一个维护温度集合的类
class Temperatures {
List<Temperature> temperatures;
}
Run Code Online (Sandbox Code Playgroud)
我想使用streams对countryName进行分组.
我想要的是
public Map<String, Temperatures> temperaturesByCountry()
Run Code Online (Sandbox Code Playgroud)
但我无法使用流将温度作为地图值,我得到的是温度列表.
我的分组实现如下
Map<String, List<Temperature>> result = this.getTemperatures()
.stream()
.collect(Collectors.groupingBy(Temperature::getCountry));
Run Code Online (Sandbox Code Playgroud)
我想要Map<String, Temperatures>而不是Map<String, List<Temperature>>
我怎样才能做到这一点.
假设我有一个简单的列表:
List<String> listOne = Arrays.asList("str1", "result1", "test", "str4", "result2", "test", "str7", "str8");
Run Code Online (Sandbox Code Playgroud)
目标是"测试",我想将目标之前的值添加到新列表中,因此输出将是[result1, result2].
使用类似的东西添加"测试"值很容易,listTwo = listOne.stream().filter(i -> i.equals("test")).collect(Collectors.toList());但是如何根据目标的位置获取其他值(在我的示例中,它只是目标之前的元素)
我试着只是改变了i到i - 1但没有采取任何行动.
我知道我可以用一个简单的for循环来做,但只是想知道如何在流中应用相同的逻辑.
for (int i = 1; i < listOne.size(); i++) {
if (listOne.get(i).equals("test")) {
listTwo.add(listOne.get(i - 1));
}
}
Run Code Online (Sandbox Code Playgroud) java ×10
java-stream ×10
java-8 ×8
arrays ×1
collections ×1
grouping ×1
hashmap ×1
merge ×1
sorting ×1
void ×1