我想要更改所有项目list.
这样做的正确方法是什么java8?
public class TestIt {
public static void main(String[] args) {
ArrayList<String> l = new ArrayList<>();
l.add("AB");
l.add("A");
l.add("AA");
l.forEach(x -> x = "b" + x);
System.out.println(l);
}
}
Run Code Online (Sandbox Code Playgroud) 考虑以下情况:我们使用Java 8并行流来执行并行forEach循环,例如,
IntStream.range(0,20).parallel().forEach(i -> { /* work done here */})
Run Code Online (Sandbox Code Playgroud)
并行线程的数量由系统属性"java.util.concurrent.ForkJoinPool.common.parallelism"控制,通常等于处理器的数量.
现在假设我们想限制特定工作的并行执行次数 - 例如因为该部分是内存密集型而内存约束意味着并行执行的限制.
限制并行执行的一种明显而优雅的方法是使用信号量(这里建议),例如,下面的代码片段将并行执行的数量限制为5:
final Semaphore concurrentExecutions = new Semaphore(5);
IntStream.range(0,20).parallel().forEach(i -> {
concurrentExecutions.acquireUninterruptibly();
try {
/* WORK DONE HERE */
}
finally {
concurrentExecutions.release();
}
});
Run Code Online (Sandbox Code Playgroud)
这很好用!
但是:在worker(at /* WORK DONE HERE */)中使用任何其他并行流可能会导致死锁.
对我来说,这是一个意外的行为.
说明:由于Java流使用ForkJoin池,因此内部forEach正在分叉,并且连接似乎正在等待.但是,这种行为仍然是出乎意料的.请注意,如果设置"java.util.concurrent.ForkJoinPool.common.parallelism"为1 ,并行流甚至可以工作.
另请注意,如果存在内部并行forEach,则它可能不透明.
问题: 这种行为是否符合Java 8规范(在这种情况下,它意味着禁止在并行流工作者中使用信号量)或者这是一个错误?
为方便起见:下面是一个完整的测试用例.除了"true,true"之外,两个布尔值的任何组合都有效,这会导致死锁.
澄清:为了明确这一点,让我强调一个方面:acquire信号量不会发生死锁.请注意,代码包含
如果该段代码使用另一个并行流,则死锁发生在2. 然后在OTHER流内发生死锁.因此,似乎不允许一起使用嵌套并行流和阻塞操作(如信号量)!
请注意,记录并行流使用ForkJoinPool并且ForkJoinPool和Semaphore属于同一个包 - java.util.concurrent(因此可以预期它们可以很好地互操作).
/*
* (c) Copyright Christian P. Fries, …Run Code Online (Sandbox Code Playgroud) 以下类包含一个成员变量runnable,该变量使用匿名内部类的实例进行初始化.内部类引用相同的成员:
class Example {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(runnable);
}
};
}
Run Code Online (Sandbox Code Playgroud)
只要在分配成员之前未执行该方法并且JLS允许这样的引用,这就不是问题.
理论上,成员变量的声明可以转换为lambda表达式,如下所示:
Runnable runnable = () -> System.out.println(runnable);
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这在功能上等同于前面的示例,但它被javac 1.8.0_05以下错误消息拒绝:
Error:(2, 54) java: self-reference in initializer
Run Code Online (Sandbox Code Playgroud)
虽然这种说法是正确的,但我不明白为什么不允许这样做.这是故意不允许的,可能是因为lambda表达式被编译为不同的字节代码,如果它被允许会导致问题?或者刚被禁止,因为这些引用在匿名内部类中使用时已经存在问题?还是JLS作家无意中不允许这样做?或者它是一个错误javac?
我认为流API在这里使代码更容易阅读.我发现了一些很烦人的东西.的Stream接口(java.util.stream.Stream)延伸的AutoClosable接口(java.lang.AutoCloseable)
因此,如果要正确关闭流,则必须使用try with resources.
清单1.不太好,溪流没有关闭.
public void noTryWithResource() {
Set<Integer> photos = new HashSet<Integer>(Arrays.asList(1, 2, 3));
@SuppressWarnings("resource") List<ImageView> collect = photos.stream()
.map(photo -> new ImageView(new Image(String.valueOf(photo)))).collect(Collectors.<ImageView>toList());
}
Run Code Online (Sandbox Code Playgroud)
清单2.2个imbricated尝试:(
public void tryWithResource() {
Set<Integer> photos = new HashSet<Integer>(Arrays.asList(1, 2, 3));
try (Stream<Integer> stream = photos.stream()) {
try (Stream<ImageView> map = stream
.map(photo -> new ImageView(new Image(String.valueOf(photo))))) {
List<ImageView> collect = map.collect(Collectors.<ImageView>toList());
}
}
}
Run Code Online (Sandbox Code Playgroud)
清单3.当map返回流时,必须关闭stream()和map() …
假设我有一个Java IntStream,是否可以将其转换为具有累积总和的IntStream?例如,以[4,2,6,...]开头的流应转换为[4,6,12,...].
更一般地说,应该如何实现有状态流操作?感觉这应该是可能的:
myIntStream.map(new Function<Integer, Integer> {
int sum = 0;
Integer apply(Integer value){
return sum += value;
}
);
Run Code Online (Sandbox Code Playgroud)
有明显的限制,这只适用于顺序流.但是,Stream.map明确需要无状态映射函数.我是否正确错过了Stream.statefulMap或Stream.cumulative操作,还是缺少Java流的重点?
比较一下Haskell,其中scanl1函数正好解决了这个例子:
scanl1 (+) [1 2 3 4] = [1 3 6 10]
Run Code Online (Sandbox Code Playgroud) 我正在查看Map界面的Java源代码,并遇到了这一小段代码:
/**
* Returns a comparator that compares {@link Map.Entry} in natural order on value.
*
* <p>The returned comparator is serializable and throws {@link
* NullPointerException} when comparing an entry with null values.
*
* @param <K> the type of the map keys
* @param <V> the {@link Comparable} type of the map values
* @return a comparator that compares {@link Map.Entry} in natural order on value.
* @see Comparable
* @since 1.8
*/
public static <K, …Run Code Online (Sandbox Code Playgroud) 我有以下目录结构:
/path/to/stuff/org/foo/bar/
/path/to/stuff/org/foo/bar/1.2.3/
/path/to/stuff/org/foo/bar/1.2.3/myfile.ext
/path/to/stuff/org/foo/bar/1.2.4/
/path/to/stuff/org/foo/bar/1.2.4/myfile.ext
/path/to/stuff/org/foo/bar/blah/
/path/to/stuff/org/foo/bar/blah/2.1/
/path/to/stuff/org/foo/bar/blah/2.1/myfile.ext
/path/to/stuff/org/foo/bar/blah/2.2/
/path/to/stuff/org/foo/bar/blah/2.2/myfile.ext
Run Code Online (Sandbox Code Playgroud)
我想得到以下输出:
/path/to/stuff/org/foo/bar/
/path/to/stuff/org/foo/bar/blah/
Run Code Online (Sandbox Code Playgroud)
我有以下代码(下面),这是低效的,因为它打印出来:
/path/to/stuff/org/foo/bar/
/path/to/stuff/org/foo/bar/
/path/to/stuff/org/foo/bar/blah/
/path/to/stuff/org/foo/bar/blah/
Run Code Online (Sandbox Code Playgroud)
这是Java代码:
public class LocatorTest
{
@Test
public void testLocateDirectories()
throws IOException
{
long startTime = System.currentTimeMillis();
Files.walk(Paths.get("/path/to/stuff/"))
.filter(Files::isDirectory)
.forEach(Foo::printIfArtifactVersionDirectory);
long endTime = System.currentTimeMillis();
System.out.println("Executed in " + (endTime - startTime) + " ms.");
}
static class Foo
{
static void printIfArtifactVersionDirectory(Path path)
{
File f = path.toAbsolutePath().toFile();
List<String> filePaths = Arrays.asList(f.list(new MyExtFilenameFilter()));
if (!filePaths.isEmpty())
{
System.out.println(path.getParent());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
过滤器: …
简而言之,我有这个代码,我想使用条件和lambda获取数组的特定元素.代码将是这样的:
Preset[] presets = presetDALC.getList();
Preset preset = Arrays.stream(presets).select(x -> x.getName().equals("MyString"));
Run Code Online (Sandbox Code Playgroud)
但显然这不起作用.在C#中会有类似的东西,但在Java中,我该怎么做?
我有一些CompletableFutures,我想并行运行它们,等待正常返回的第一个.
我知道我可以CompletableFuture.anyOf用来等待第一次返回,但这将正常或异常返回.我想忽略异常.
List<CompletableFuture<?>> futures = names.stream().map(
(String name) ->
CompletableFuture.supplyAsync(
() ->
// this calling may throw exceptions.
new Task(name).run()
)
).collect(Collectors.toList());
//FIXME Can not ignore exceptionally returned takes.
Future any = CompletableFuture.anyOf(futures.toArray(new CompletableFuture<?>[]{}));
try {
logger.info(any.get().toString());
} catch (Exception e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)