所以我只是学习新的Java 8,特别是lambdas和日期和时间api.我把它与scala进行比较.我的基本想法是找到命令行,流和并行流之间的执行时间差异.所以我决定创建一个Library应用程序并执行搜索,过滤,排序等操作.我创建了一个Library类,其中包含一个名为books的列表字段,并填充了1000本书.然后为搜索创建了一个功能界面,并在所有三种样式中进行了一些操作.一切都很好.我的代码是:
// Functional Interface
interface Search<T> {
public void search(T t);
}
// Library class
final Library library = new Library();
// This just creates some random book objects.
final List<Book> books = collectBooks();
final Search<List<Book>> parallelSearch = (bks) -> library.findAndPrintBooksParallel(bks);
// Parallel Operations
private void findAndPrintBooksParallel(List<Book> books) {
books.parallelStream()
.filter(b -> b.getAuthor().equals("J.K. Rowling"))
.sorted((x,y) -> x.getAuthor().compareTo(y.getAuthor()))
.map(Book::getIsbn)
.forEach(Library::waitAndPrintRecord);
}
Run Code Online (Sandbox Code Playgroud)
现在我尝试在scala中重新创建相同的程序,看看执行是否更快?令人惊讶的是scala不允许我进行并行排序(或者可能是我在这里无知).我的scala库是
// Again some random book objects as a list
val books = collectBooks
// Parallel operation
books.par filter(_.author …Run Code Online (Sandbox Code Playgroud) 为什么要forEach以随机顺序打印数字,同时collect始终按原始顺序收集元素,即使是从并行流中收集?
Integer[] intArray = {1, 2, 3, 4, 5, 6, 7, 8};
List<Integer> listOfIntegers = new ArrayList<>(Arrays.asList(intArray));
System.out.println("Parallel Stream: ");
listOfIntegers
.stream()
.parallel()
.forEach(e -> System.out.print(e + " "));
System.out.println();
// Collectors
List<Integer> l = listOfIntegers
.stream()
.parallel()
.collect(Collectors.toList());
System.out.println(l);
Run Code Online (Sandbox Code Playgroud)
输出:
Parallel Stream:
8 1 6 2 7 4 5 3
[1, 2, 3, 4, 5, 6, 7, 8]
Run Code Online (Sandbox Code Playgroud) 我想借此List<Pojo>和return一个Map<String, List<Pojo>>其中Map的关键是String价值Pojo,让我们把它String key.
澄清一下,给出以下内容:
Pojo 1:Key:值:1
Pojo 2:Key:值:2
Pojo 3:键:b值:3
Pojo 4:键:b值:4
我想要一个Map<String, List<Pojo>>与keySet()大小的2,其中键"a"具有的POJO 1和2,和键"b"具有的POJO 3和4.
我怎样才能使用Java 8 lambdas最好地实现这一目标?
JDK 8 EA现在已经出局了,我只是想习惯lambda和新的Stream API.我试图用并行流对列表进行排序,但结果总是错误的:
import java.util.ArrayList;
import java.util.List;
public class Test
{
public static void main(String[] args)
{
List<String> list = new ArrayList<>();
list.add("C");
list.add("H");
list.add("A");
list.add("A");
list.add("B");
list.add("F");
list.add("");
list.parallelStream() // in parallel, not just concurrently!
.filter(s -> !s.isEmpty()) // remove empty strings
.distinct() // remove duplicates
.sorted() // sort them
.forEach(s -> System.out.println(s)); // print each item
}
}
Run Code Online (Sandbox Code Playgroud)
OUTPUT:
C
F
B
H
A
Run Code Online (Sandbox Code Playgroud)
请注意,每次输出都不同.我的问题是,这是一个错误吗?或者不可能并行排序列表?如果是这样,那么为什么JavaDoc没有声明呢?最后一个问题,还有另一个操作,其输出会根据流类型而有所不同吗?
在Java 8中,Stream该类没有任何方法来包装Iterable.
相反,我Spliterator从这里Iterable获得了,然后Stream从StreamSupport这样获得一个:
boolean parallel = true;
StreamSupport.stream(spliterator(), parallel)
.filter(Row::isEmpty)
.collect(Collectors.toList())
.forEach(this::deleteRow);
Run Code Online (Sandbox Code Playgroud)
是否有产生的一些其他的方式Stream上的操作Iterable,我很想念?
我在这个函数式编程和流程方面有点绿色,但我知道的一点点非常有用!
我已经多次出现这种情况了:
List<SomeProperty> distinctProperties = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.toList());
if (distinctProperties.size() == 1) {
SomeProperty commonProperty = distinctProperties.get(0);
// take some action knowing that all share this common property
}
Run Code Online (Sandbox Code Playgroud)
我真正想要的是:
Optional<SomeProperty> universalCommonProperty = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.singleOrEmpty());
Run Code Online (Sandbox Code Playgroud)
我认为singleOrEmpty除了与之相结合之外,这个东西在其他情况下也很有用distinct.当我是一个超级n00b时,我花了很多时间重新发明Java Collections Framework,因为我不知道它在那里,所以我不想重复我的错误.Java是否有一个很好的方法来做这singleOrEmpty件事?我错误地制定了它吗?
谢谢!
编辑:这是distinct案例的一些示例数据.如果您忽略该map步骤:
Optional<SomeProperty> universalCommonProperty = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.singleOrEmpty());
[] -> Optional.empty()
[1] -> Optional.of(1)
[1, 1] -> Optional.of(1)
[2, 2] -> Optional.of(2) …Run Code Online (Sandbox Code Playgroud) 我已经阅读过这个和这个问题,但仍然怀疑Stream.skipJDK作者是否打算观察到这种行为.
让我们简单输入数字1..20:
List<Integer> input = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
现在让我们创建一个并行流,以不同的方式结合unordered()使用skip()并收集结果:
System.out.println("skip-skip-unordered-toList: "
+ input.parallelStream().filter(x -> x > 0)
.skip(1)
.skip(1)
.unordered()
.collect(Collectors.toList()));
System.out.println("skip-unordered-skip-toList: "
+ input.parallelStream().filter(x -> x > 0)
.skip(1)
.unordered()
.skip(1)
.collect(Collectors.toList()));
System.out.println("unordered-skip-skip-toList: "
+ input.parallelStream().filter(x -> x > 0)
.unordered()
.skip(1)
.skip(1)
.collect(Collectors.toList()));
Run Code Online (Sandbox Code Playgroud)
过滤步骤在这里基本没什么,但为流引擎增加了更多的难度:现在它不知道输出的确切大小,因此关闭了一些优化.我有以下结果:
skip-skip-unordered-toList: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
// absent values: 1, 2
skip-unordered-skip-toList: …Run Code Online (Sandbox Code Playgroud) 是否有更好的功能方式将"key:value"形式的字符串数组转换为Map使用Java 8 lambda语法?
Arrays.asList("a:1.0", "b:2.0", "c:3.0")
.stream()
.map(elem -> elem.split(":")
.collect(Collectors.toMap(keyMapper?, valueMapper?));
Run Code Online (Sandbox Code Playgroud)
我现在的解决方案似乎没有真正的功能:
Map<String, Double> kvs = new HashMap<>();
Arrays.asList("a:1.0", "b:2.0", "c:3.0")
.stream()
.map(elem -> elem.split(":"))
.forEach(elem -> kvs.put(elem[0], Double.parseDouble(elem[1])));
Run Code Online (Sandbox Code Playgroud) 我上课了
class Foo{
String name;
// setter, getter
}
Run Code Online (Sandbox Code Playgroud)
它只有一个默认的构造函数.
然后,我试图Foo从一些字符串创建一个List :
Arrays.stream(fooString.split(","))
.map(name -> {
Foo x = new Foo();
x.setName(name);
return x;
}).collect(Collectors.toList()));
Run Code Online (Sandbox Code Playgroud)
由于没有构造函数采用名称,我不能简单地使用方法引用.当然,我可以使用构造函数调用和setter将这三行提取到一个方法中,但有没有更好或简洁的方法呢?(不更改Foo,这是生成的文件)
通过Katas在工作中发布的一些编码,我偶然发现了这个问题,我不知道如何解决.
使用Java 8 Streams,给定正整数列表,生成一个整数列表,其中整数前面有一个更大的值.
Run Code Online (Sandbox Code Playgroud)[10, 1, 15, 30, 2, 6]以上输入将产生:
Run Code Online (Sandbox Code Playgroud)[1, 15, 2]因为1在15之前,15在30之前,2在6之前.
public List<Integer> findSmallPrecedingValues(final List<Integer> values) {
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < values.size(); i++) {
Integer next = (i + 1 < values.size() ? values.get(i + 1) : -1);
Integer current = values.get(i);
if (current < next) {
result.push(current);
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我无法弄清楚如何在lambda中访问下一个.
return values.stream().filter(v -> v < next).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
map并映射到a …java ×10
java-stream ×10
java-8 ×9
lambda ×4
collectors ×1
iterable ×1
scala ×1
spliterator ×1