我正在寻找一种简洁的方法来过滤掉特定索引中List中的项目.我的示例输入如下所示:
List<Double> originalList = Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
List<Integer> filterIndexes = Arrays.asList(2, 4, 6, 8);
Run Code Online (Sandbox Code Playgroud)
我想筛选出的索引项2,4,6,8.我有一个for循环跳过与索引匹配的项目,但我希望有一种简单的方法可以使用流来完成.最终结果如下:
List<Double> filteredList = Arrays.asList(0.0, 1.0, 3.0, 5.0, 7.0, 9.0, 10.0);
Run Code Online (Sandbox Code Playgroud) 所以我知道,如果你使用parallelStream没有自定义ForkJoinPool,它将使用默认的ForkJoinPool,默认情况下,只有一个线程,因为你有处理器.
因此,如此处所述(以及该问题的另一个答案)为了获得更多的并行性,您必须:
将并行流执行提交给您自己的ForkJoinPool:yourFJP.submit(() - > stream.parallel().forEach(doSomething));
所以,我这样做了:
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.IntStream;
import com.google.common.collect.Sets;
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ForkJoinPool forkJoinPool = new ForkJoinPool(1000);
IntStream stream = IntStream.range(0, 999999);
final Set<String> thNames = Collections.synchronizedSet(new HashSet<String>());
forkJoinPool.submit(() -> {
stream.parallel().forEach(n -> {
System.out.println("Processing n: " + n);
try {
Thread.sleep(500);
thNames.add(Thread.currentThread().getName());
System.out.println("Size: " + thNames.size() + " activeCount: " + forkJoinPool.getActiveThreadCount());
} catch (Exception e) { …Run Code Online (Sandbox Code Playgroud) 考虑这些类和累积函数,它们代表了我原始上下文的简化(但是再现了同样的问题):
abstract static class Foo {
abstract int getK();
}
static class Bar extends Foo {
int k;
Bar(int k) { this.k = k; }
int getK() { return this.k; }
}
private static Foo combined(Foo a1, Foo a2) {
return new Bar(a1.getK() + a2.getK());
}
Run Code Online (Sandbox Code Playgroud)
我试图通过依赖单独的函数来执行项目的累积(最初的数据索引报告)combined,该函数直接处理类型的元素Foo.
Foo outcome = Stream.of(1,2,3,4,5)
.map(Bar::new)
.reduce((a,b) -> combined(a, b))
.get();
Run Code Online (Sandbox Code Playgroud)
事实证明,此代码导致编译错误(OpenJDK"1.8.0_92"):"lambda表达式中的错误返回类型:Foo无法转换为Bar".编译器坚持尝试使用Bar累积元素来减少流,即使Foo累积函数的参数和返回类型都有公共类型.
我还发现,只要我明确地将流映射到Foos 流中,我仍然可以采用这种方法:
Foo outcome = Stream.of(1,2,3,4,5)
.<Foo>map(Bar::new)
.reduce((a,b) -> combined(a, …Run Code Online (Sandbox Code Playgroud) 我想在地图上执行延迟操作,所以我正在使用Timer,我传递的是TimerTask一个延迟,以毫秒为单位:
timer.schedule(new TimerTask() {
public void run() {
tournaments.remove(id);
}
}, delay);
Run Code Online (Sandbox Code Playgroud)
这是一种类似原始缓存的功能,我在刚刚创建的新资源上设置了到期时间.
我以为我可以使用lambdas做到这一点,如下所示:
times.schedule(() -> tournaments.remove(id), delay);
Run Code Online (Sandbox Code Playgroud)
但是编译器说这不能做到.为什么?我究竟做错了什么?我可以使用lambdas来实现更简洁的代码,或者在这里根本不可能,我应该坚持使用匿名类吗?
我想用Java 8编写纯函数,将集合作为参数,对该集合的每个对象应用一些更改,并在更新后返回一个新集合.我想遵循FP原则,所以我不想更新/修改作为参数传递的集合.
有没有办法使用Stream API而不先创建原始集合的副本(然后使用forEach或'normal'for循环)?
下面的示例对象,并假设我想将文本追加到其中一个对象属性:
public class SampleDTO {
private String text;
}
Run Code Online (Sandbox Code Playgroud)
所以我想做类似下面的事情,但不修改集合.假设"列表"是一个List<SampleDTO>.
list.forEach(s -> {
s.setText(s.getText()+"xxx");
});
Run Code Online (Sandbox Code Playgroud) 我有一个int流,并希望该流的每个元素进行一些计算,并将它们作为Map返回,其中键是int值,值是该计算的结果.我写了下面这段代码:
IntStream.range(0,10).collect(Collectors.toMap(Function.identity(), i -> computeSmth(i)));
Run Code Online (Sandbox Code Playgroud)
哪里computeSmth(Integer a).我有下一个编译器错误
method collect in interface java.util.stream.IntStream cannot be applied to given types;
required: java.util.function.Supplier<R>,java.util.function.ObjIntConsumer<R>,java.util.function.BiConsumer<R,R>
found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.Map<java.lang.Object,java.lang.String>>
reason: cannot infer type-variable(s) R
(actual and formal argument lists differ in length)
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
假设我们有一些像这样的测试接口/类:
abstract class Plant {
public abstract String getName();
}
interface Eatable { }
class Apple extends Plant implements Eatable {
@Override
public String getName() {
return "Apple";
}
}
class Rose extends Plant {
@Override
public String getName() {
return "Rose";
}
}
interface Animal {
<T extends Plant & Eatable> void eat(T plant);
}
Run Code Online (Sandbox Code Playgroud)
您可以看到Animal.eat具有约束的通用方法.现在我的Human班级是这样的:
class Human implements Animal {
@Override
public void eat(Plant plant) {
}
}
Run Code Online (Sandbox Code Playgroud)
编译好.你可以看到Human.eat比限制较少Animal.eat,因为Eatable …
我在我的Android项目中使用Java 8.我已经设置了Jack(在Android应用程序模块中)和Retrolambda(在其他模块中).
我遇到的问题是当我尝试使用类变量(并且我可以在任何模块中重现它)时,我的Lambda表达式在一个特定场景中崩溃,在所有其他情况下,它按预期工作.也许这是标准的Java行为,但到目前为止我找不到任何解释.有谁知道问题在哪里?我的班级和崩溃如下:
public class LambdaBugTest {
private final String parentClassVariableString = "parentClassVariableString";
public void testLambdas() {
// ----------- THESE WORK OK --------------
final Functional simpleLambdaWorks = text -> System.out.print(text);
final Functional methodReferenceWorks = System.out::print;
final Functional interfaceWithClassParamWorks = new Functional() {
@Override
public void doSomething(String text) {
System.out.print(text + " " + parentClassVariableString);
}
};
// -----------------------------------------
// ----------- THIS ONE CRASHES ------------
final Functional lambdaWithClassParamCrashes = text -> System.out.print(text + " " + parentClassVariableString);
// -----------------------------------------
simpleLambdaWorks.doSomething("Text from …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种以Stream干净的方式优化处理的方法.
我有类似的东西:
try (Stream<Path> stream = Files.list(targetDir)) {
Map<String, List<Path>> targetDirFilteredAndMapped = stream.parallel()
.filter(path -> sd.containsKey(md5(path)))
.collect(Collectors.groupingBy(path -> md5(path)));
} catch (IOException ioe) { // manage exception }
Run Code Online (Sandbox Code Playgroud)
由于该md5功能非常昂贵,我想知道是否有办法每个文件只调用一次.
有什么建议?
为了获得Java新流的一些经验,我一直在开发一个处理扑克牌的框架.这是我的代码的第一个版本,用于创建Map包含手中每个套装的卡数(Suit是enum):
Map<Suit, Long> countBySuit = contents.stream() // contents is ArrayList<Card>
.collect( Collectors.groupingBy( Card::getSuit, Collectors.counting() ));
Run Code Online (Sandbox Code Playgroud)
这很好用,我很高兴.然后我重构,为"Suit Cards"和Jokers创建单独的Card子类.所以这个getSuit()方法从Card类转移到了它的子类SuitCard,因为Jokers没有套装.新代码:
Map<Suit, Long> countBySuit = contents.stream() // contents is ArrayList<Card>
.filter( card -> card instanceof SuitCard ) // reject Jokers
.collect( Collectors.groupingBy( SuitCard::getSuit, Collectors.counting() ) );
Run Code Online (Sandbox Code Playgroud)
请注意巧妙地插入过滤器以确保所考虑的卡实际上是西装卡而不是小丑.但它不起作用!显然,这collect条线并没有意识到它被传递的对象是保证是一个SuitCard.
在困惑了一段时间后,我绝望地尝试插入一个map函数调用,令人惊讶的是它有效!
Map<Suit, Long> countBySuit = contents.stream() // contents is ArrayList<Card>
.filter( card -> card instanceof SuitCard ) // reject …Run Code Online (Sandbox Code Playgroud) java-8 ×10
java ×8
java-stream ×5
lambda ×3
android ×1
casting ×1
concurrency ×1
generics ×1
retrolambda ×1