我正在尝试学习如何在我的日常编程中使用Java 8功能(例如lambdas和流),因为它使代码更清晰.
以下是我目前正在处理的内容:我从本地文件中获取一个字符串流,其中包含一些数据,稍后我将这些数据转换为对象.输入文件结构如下所示:
Airport name; Country; Continent; some number;
Run Code Online (Sandbox Code Playgroud)
我的代码看起来像这样:
public class AirportConsumer implements AirportAPI {
List<Airport> airports = new ArrayList<Airport>();
@Override
public Stream<Airport> getAirports() {
Stream<String> stream = null;
try {
stream = Files.lines(Paths.get("resources/planes.txt"));
stream.forEach(line -> createAirport(line));
} catch (IOException e) {
e.printStackTrace();
}
return airports.stream();
}
public void createAirport(String line) {
String airport, country, continent;
int length;
airport = line.substring(0, line.indexOf(';')).trim();
line = line.replace(airport + ";", "");
country = line.substring(0,line.indexOf(';')).trim();
line = line.replace(country + ";", "");
continent = …Run Code Online (Sandbox Code Playgroud) 让我们说我有以下数组:{1,2,3,4,6,7,8}放入一个Stream<Integer> s = Stream.of(1,2,3,4,6,7,8);
如何在Java lambda表达式和Stream函数中使用来计算每个元素和下一个元素之间的差异(在本例中{1,1,1,2,1,1})?这不是真正的reduce操作,因为reduce将整个列表转换为1个元素; 它也不是地图操作,因为它需要两个元素来计算差异,而不仅仅是一个.
我有这样的文本文件:
ids.txt
1000
999
745
123
...
Run Code Online (Sandbox Code Playgroud)
我想读取此文件并将其加载到二维数组中.我希望有一个类似于下面的数组:
Object[][] data = new Object[][] { //
{ new Integer(1000) }, //
{ new Integer(999) }, //
{ new Integer(745) }, //
{ new Integer(123) }, //
...
};
Run Code Online (Sandbox Code Playgroud)
这是我写的代码:
File idsFile = ... ;
try (Stream<String> idsStream = Files.lines(idsFile.toPath(), StandardCharsets.US_ASCII)) {
Object[][] ids = idsStream
.filter(s -> s.trim().length() > 0)
.toArray(size -> new Object[size][]);
// Process ids array here...
}
Run Code Online (Sandbox Code Playgroud)
运行此代码时,会引发异常:
java.lang.ArrayStoreException: null
at java.lang.System.arraycopy(Native Method) ~[na:1.8.0_45]
at java.util.stream.SpinedBuffer.copyInto(Unknown Source) ~[na:1.8.0_45] …Run Code Online (Sandbox Code Playgroud) 我无法解释这一点,但我在其他人的代码中发现了这种现象:
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.util.stream.Stream;
import org.junit.Test;
public class TestDidWeBreakJavaAgain
{
@Test
public void testIoInSerialStream()
{
doTest(false);
}
@Test
public void testIoInParallelStream()
{
doTest(true);
}
private void doTest(boolean parallel)
{
Stream<String> stream = Stream.of("1", "2", "3");
if (parallel)
{
stream = stream.parallel();
}
stream.forEach(name -> {
try
{
Files.createTempFile(name, ".dat");
}
catch (IOException e)
{
throw new UncheckedIOException("Failed to create temp file", e);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
在启用安全管理器的情况下运行时,仅仅调用parallel()流,或者parallelStream()从集合中获取流时,似乎可以保证所有执行I/O的尝试都会抛出SecurityException.(最有可能的,它调用任何方法可以抛出 …
我目前这样做:
Set<Integer> integers = ... // sourced from elsewhere in code
IntStream intStream = integers.stream().mapToInt(value -> value);
Run Code Online (Sandbox Code Playgroud)
将值映射到值,将转换为Stream<Integer>to 似乎是多余的IntStream.有没有办法在没有冗余mapToInt(...)部分的情况下做到这一点?
我想获取一组对象(ObjectInstance在这种情况下),我想将它们分组为一个属性,并将结果列表排序在另一个属性上.
Set<ObjectInstance> beans = server.queryMBeans(null, null);
Map<String, List<String>> beansByDomain = beans.stream()
.collect(groupingBy( (ObjectInstance oi) -> oi.getObjectName().getDomain(),
mapping((ObjectInstance oi) -> oi.getObjectName().getCanonicalKeyPropertyListString(),
toList() )));
Run Code Online (Sandbox Code Playgroud)
上面的表达式创建了正确的数据结构:Map键是ObjectInstance对象的域,其中值是属性列表的列表.我想要的是现在对列表进行排序,以确保它们按字母顺序排列.有没有办法在同一个表达式中执行此操作?
一个想法是添加.sort()权后.stream(),但真正保证工作?
我正在从丑陋的嵌套for循环转换为java中漂亮的设计lambda表达式.
这是我的实际代码
for (String foo : foos) {
for (Bar bar : bars) {
if (bar.getFoo().equals(foo)) {
FooBar fooBar = new FooBar();
fooBar.setBar(bar);
listOfFooBar.add(fooBar);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的实际lambda代码替换上面的代码
foos.forEach(i -> bars.stream().filter(p -> p.getFoo().equals(i)).findFirst().ifPresent(p -> {
FooBar s = new FooBar();
fooBar.setBar(bar);
listOfFooBar.add(fooBar);
}));
Run Code Online (Sandbox Code Playgroud)
我的问题是,有一种方法可以填充listOfFooBar某种collect()方法吗?
就像是 listOfFooBar = foos.forEach(.....).collect(Collectors.toList());
一个事实是,条形图总是包含每个foo,foos基本上是条形图的一小部分.
如果有更好的方法(在性能或优雅方面)做那个lambda,请分享.
我正在尝试将双打列表流式传输到a Map<Double, Double>,其中键是原始列表中的双打,并且值是一些计算值.
这就是我的代码:
// "values" is a List<Double> that was passed in
ImmutableMap<Double, Double> valueMap = values.parallelStream()
.collect(Collectors.toMap(p -> p, p -> doThing(values, p)));
private Double doThing(List<Double>, Double p) {
Double computedValue = 0.0;
// Do math here with p
return computedValue;
}
Run Code Online (Sandbox Code Playgroud)
然而,IntelliJ抱怨这p -> p不是一个有效的lambda表达式 - 它抱怨循环推理.我打电话时也遇到错误doThing,因为p是lambda参数而不是Double.
当我在调用中尝试强制p转换为无法投射时.DoubledoThing
我错过了一些非常明显的东西吗 似乎没有办法真正对我的lambda参数做任何事情......
try (Stream<String> lines = Files.lines(targetFile)) {
List<String> replacedContent = lines.map(line ->
StringUtils.replaceEach(line,keys, values))
.parallel()
.collect(Collectors.toList());
Files.write(targetFile, replacedContent);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试替换文件的每一行中的多个文本模式.但我观察到"\ r \n"(字节等效10和13)正被替换为"\ r"(仅为10)并且我的比较测试失败了.
我想保留输入文件中的换行符,并且不希望java触及它们.任何人都可以建议是否有办法这样做而不必使用单独的默认替换"\ r \n".
我有以下课程:
public class Item {
int id;
String name;
// few other fields, contructor, getters and setters
}
Run Code Online (Sandbox Code Playgroud)
我有一个项目清单.我想迭代列表并找到具有特定id的实例.我正试图通过溪流来做.
public void foobar() {
List<Item> items = getItemList();
List<Integer> ids = getIdsToLookup();
int id, i = ids.size() - 1;
while (i >= 0) {
id = ids.get(i);
Optional<Item> item = items
.stream()
.filter(a -> a.getId() == id)
.findFirst();
// do stuff
i--;
}
}
Run Code Online (Sandbox Code Playgroud)
这是迭代列表并获得我需要的元素的最佳方法吗?另外,我在id的过滤行上得到一个错误,它表示lambda表达式中使用的变量必须是final或者有效的final.也许我可以在while循环中定义id,这应该摆脱异常.谢谢.