Java Streams - 将两个字符串行分别映射到一个对象
Java Streams - Map two string lines each to one object
假设我们有一个包含 (product name, price)
对的文本文件。每对在文本文件中占据两行,其中第一行对应产品名称,第二行对应该产品的价格。我们可以假设文本文件的格式正确(并且行数相等)
示例:
Ice Cream
.99
Chocolate
.00
Nice Shoes
.95
...
现在我有一个简单的 class 表示这样的对:
public class Product {
private final String name;
private final int price;
public Product(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return this.name;
}
public int getPrice() {
return this.price;
}
}
我们读取了包含对的文件,现在有一个包含所有单独行的字符串数组。我需要使用 Streams 将每两行映射到一个 Product
.
类型的对象
如何将两行分别分组,然后将它们映射到 Product
?如果有一个简单的方法,它是否仍然适用于并行流?
如果你有数组中的项目,你可以使用 vanilla java 和 intStream 并过滤偶数值,然后在下一个映射中你可以使用索引和索引+1。也许看看here
您可以制作自己的 Collector
,临时存储之前的 element/string。当当前元素以 $
开头时,产品名称存储在 prev
中。现在您可以将价格转换为双精度并创建对象。
private class ProductCollector {
private final List<Product> list = new ArrayList<>();
private String prev;
public void accept(String str) {
if (prev != null && str.startsWith("$")) {
double price = Double.parseDouble(str.substring(1));
list.add(new Product(prev, price));
}
prev = str;
}
public List<Product> finish() {
return list;
}
public static Collector<String, ?, List<Product>> collector() {
return Collector.of(ProductCollector::new, ProductCollector::accept, (a, b) -> a, ProductCollector::finish);
}
}
由于需要依赖序列(价格行在名称行之后),流无法并行处理。以下是使用自定义收集器的方法:
String[] lines = new String[]{
"Ice Cream", ".99",
"Chocolate", ".00",
"Nice Shoes", ".95"
};
List<Product> products = Stream.of(lines)
.sequential()
.collect(ProductCollector.collector());
请注意,您的价格不是整数,这就是为什么我使用双精度来正确表示它们的原因。
假设我们有一个包含 (product name, price)
对的文本文件。每对在文本文件中占据两行,其中第一行对应产品名称,第二行对应该产品的价格。我们可以假设文本文件的格式正确(并且行数相等)
示例:
Ice Cream
.99
Chocolate
.00
Nice Shoes
.95
...
现在我有一个简单的 class 表示这样的对:
public class Product {
private final String name;
private final int price;
public Product(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return this.name;
}
public int getPrice() {
return this.price;
}
}
我们读取了包含对的文件,现在有一个包含所有单独行的字符串数组。我需要使用 Streams 将每两行映射到一个 Product
.
如何将两行分别分组,然后将它们映射到 Product
?如果有一个简单的方法,它是否仍然适用于并行流?
如果你有数组中的项目,你可以使用 vanilla java 和 intStream 并过滤偶数值,然后在下一个映射中你可以使用索引和索引+1。也许看看here
您可以制作自己的 Collector
,临时存储之前的 element/string。当当前元素以 $
开头时,产品名称存储在 prev
中。现在您可以将价格转换为双精度并创建对象。
private class ProductCollector {
private final List<Product> list = new ArrayList<>();
private String prev;
public void accept(String str) {
if (prev != null && str.startsWith("$")) {
double price = Double.parseDouble(str.substring(1));
list.add(new Product(prev, price));
}
prev = str;
}
public List<Product> finish() {
return list;
}
public static Collector<String, ?, List<Product>> collector() {
return Collector.of(ProductCollector::new, ProductCollector::accept, (a, b) -> a, ProductCollector::finish);
}
}
由于需要依赖序列(价格行在名称行之后),流无法并行处理。以下是使用自定义收集器的方法:
String[] lines = new String[]{
"Ice Cream", ".99",
"Chocolate", ".00",
"Nice Shoes", ".95"
};
List<Product> products = Stream.of(lines)
.sequential()
.collect(ProductCollector.collector());
请注意,您的价格不是整数,这就是为什么我使用双精度来正确表示它们的原因。