我写了这段代码:
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String... args) {
List<String> a = Arrays.asList("One", "Two", "three");
List<Integer> lengths = a.stream().mapToInt(String::length).collect(Collectors.toList());
}
}
Run Code Online (Sandbox Code Playgroud)
但它不想编译,说:
Error:(8, 68) java: 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.List<java.lang.Object>>
reason: cannot infer type-variable(s) R
(actual and formal argument lists differ in length)
Run Code Online (Sandbox Code Playgroud)
这里发生了什么事?为什么有限制?如果你使用地图.它没有mapToInt,而是工作正常.
我正在阅读java 8的实际操作,作者引用此链接:http://mail.openjdk.java.net/pipermail/lambda-dev/2013-November/011516.html
并编写自己的流forker,看起来像这样:
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Main {
public static void main(String... args) {
List<Person> people = Arrays.asList(new Person(23, "Paul"), new Person(24, "Nastya"), new Person(30, "Unknown"));
StreamForker<Person> forker = new StreamForker<>(people.stream())
.fork("All names", s -> s.map(Person::getName).collect(Collectors.joining(", ")))
.fork("Age stats", s -> s.collect(Collectors.summarizingInt(Person::getAge)))
.fork("Oldest", s -> s.reduce((p1, p2) -> p1.getAge() > p2.getAge() ? p1 : p2).get());
Results results = …Run Code Online (Sandbox Code Playgroud) multithreading blockingqueue java-8 java-stream completable-future
我在intellij中写了这个Java代码:
public class Main {
public static void main(String[] args) {
int[] a = {1,1,1,1,1,1};
for(int i = 0; i < a.length; ++i) {
a[i]++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,我在for循环中设置一个断点,就像这样.

接下来我转到"查看断点"菜单,可以通过ctrl + shift + f8进行访问,并为我的断点输入这些设置.

然后我点击调试按钮,我的输出是这样的:
void
1
void
1
void
1
void
1
void
1
void
1
Run Code Online (Sandbox Code Playgroud)
为什么intellij在输出中打印"void"?
假设您有一个人名单,罗伯茨,保罗,理查兹等,这些人按名字分组为Map<String, List<Person>>。您想找到最古老的Paul,Robert等...您可以这样做:
public static void main(String... args) {
List<Person> people = Arrays.asList(
new Person(23, "Paul"),
new Person(24, "Robert"),
new Person(32, "Paul"),
new Person(10, "Robert"),
new Person(4, "Richard"),
new Person(60, "Richard"),
new Person(9, "Robert"),
new Person(26, "Robert")
);
Person dummy = new Person(0, "");
var mapping = people.stream().collect(groupingBy(Person::getName, reducing(dummy, (p1, p2) -> p1.getAge() < p2.getAge() ? p2 : p1)));
mapping.entrySet().forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
说,我想以Map<String, Integer>而不是的形式获取映射Map<String, Person>,我可以这样做:
var mapping = people.stream().collect(groupingBy(Person::getName, mapping(Person::getAge, reducing(0, (p1, p2) -> p1 < …Run Code Online (Sandbox Code Playgroud) 我写了这段代码:
@Deprecated("Old stuff", ReplaceWith("test2"))
fun test1(i: Int) {
println("old Int = $i")
}
fun test2(i: Int) {
println("new Int = $i")
}
fun main(args: Array<String>) {
test1(3)
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,当我按Alt + Enter并单击“替换为test2”时,该方法test1消失并且没有被替换,我在做什么错?
编辑:
它确实适用于类:
@Deprecated("Old stuff", ReplaceWith("Test2"))
class Test1
class Test2
fun main(args: Array<String>) {
val a = Test1()
}
Run Code Online (Sandbox Code Playgroud) 让我们考虑一下这段代码:
@Target(AnnotationTarget.FIELD)
annotation class DeserializeInterface<T: Any>(val targetClass: KClass<T>)
interface A
class B : A
class Test {
@DeserializeInterface<B>(B::class) val a: A = B()
}
Run Code Online (Sandbox Code Playgroud)
atline X我写@DeserializeInterface<B>(B::class),而 Kotlin 不允许我只写@DeserializeInterface(B::class).
在这种情况下,它为什么不从 推断出类型参数B::class?
相比之下,类型推断在这里工作得很好:
class AClass<T: Any>(val a: List<T>)
fun main(args: Array<String>) {
val a = AClass(listOf(1,2,3))
}
Run Code Online (Sandbox Code Playgroud)
但为什么?
java 8的作者在写这个类:
class ToListCollector<T> implements Collector<T, List<T>, List<T>> {
@Override
public Supplier<List<T>> supplier() {
return ArrayList::new;
}
@Override
public BiConsumer<List<T>, T> accumulator() {
return List::add;
}
@Override
public BinaryOperator<List<T>> combiner() {
return (l1, l2) -> {
l1.addAll(l2);
return l1;
};
}
@Override
public Function<List<T>, List<T>> finisher() {
return Function.identity();
}
@Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.CONCURRENT));
}
}
Run Code Online (Sandbox Code Playgroud)
然后他谈到了特征枚举中的不同值.然后他解释了为什么他写的这个收藏家是IDENTITY_FINISH和CONCURRENT而不是UNORDERED,他说:
到目前为止开发的ToListCollector是IDENTITY_FINISH,因为用于累积流中元素的List已经是预期的最终结果,不需要任何进一步的转换,但它不是UNORDERED,因为如果你将它应用于有序流你希望在生成的List中保留此顺序.最后,它是CONCURRENT,但是按照我们刚才所说的,只有当它的底层数据源是无序的时,才会并行处理流.
为什么只有当底层源无序时才会并行处理流?我认为它仍然会并行处理,但是combiner()必须保留顺序.这本书中的错误是什么?
我认为Brian Goetz 在最后一篇文章中非常明确地谈到了这篇文章中有序流的并行处理.
书中的页面是192 - 193.
我正在阅读java 8的行动,第11章(关于CompletableFutures),它让我思考我公司的代码库.
动作书中的java 8说如果你有像我下面写的代码,你一次只能使用4 CompletableFuture秒(如果你有4核计算机).这意味着如果你想异步执行10个操作,你将首先运行前4 CompletableFuture秒,然后是第2个4,然后是剩下的2个,因为默认ForkJoinPool.commonPool()只提供等于的线程数Runtime.getRuntime().availableProcessors().
在我公司的代码库中,有一个@Service名为AsyncHelpers的类,它们包含一个方法load(),该方法使用CompletableFutures在不同的块中异步加载有关产品的信息.我想知道他们一次只使用4个线程.
我公司的代码库中有几个这样的异步助手,例如,一个用于产品列表页面(PLP),另一个用于产品详细信息页面(PDP).产品详细信息页面是专门针对特定产品的页面,显示其详细特征,交叉销售产品,类似产品和更多内容.
有一个架构决定以块的形式加载pdp页面的细节.加载应该是异步发生的,当前代码使用CompletableFutures.我们来看看伪代码:
static PdpDto load(String productId) {
CompletableFuture<Details> photoFuture =
CompletableFuture.supplyAsync(() -> loadPhotoDetails(productId));
CompletableFuture<Details> characteristicsFuture =
CompletableFuture.supplyAsync(() -> loadCharacteristics(productId));
CompletableFuture<Details> variations =
CompletableFuture.supplyAsync(() -> loadVariations(productId));
// ... many more futures
try {
return new PdpDto( // construct Dto that will combine all Details objects into one
photoFuture.get(),
characteristicsFuture.get(),
variations.get(),
// .. many more future.get()s
); …Run Code Online (Sandbox Code Playgroud) 在Java中我可以这样做:
List<String> stringList = getRandomStrings(100_000, 1000);
IntSummaryStatistics stats =
stringList.stream()
.filter(Objects::nonNull)
.mapToInt(String::length)
.summaryStatistics();
System.out.println(stats);
Run Code Online (Sandbox Code Playgroud)
输出是:
IntSummaryStatistics{count=100000, sum=49868013, min=0, average=498.680130, max=999}
Run Code Online (Sandbox Code Playgroud)
linq具有相同的功能吗?或者我必须单独计算所有内容?
Java没有这一气呵成,它看起来像在C#中,你必须计算出所有成分Average(),Count(),Sum(),Min()和Max()分别.
问题出在评论中.我想引用外部函数append,而不是那个中定义的函数,StringBuilder我该怎么做?
fun append(c: Char) {
println("TEST")
}
fun sbTest() = with(StringBuilder()) {
for(c in 'A'..'Z') {
append(c) // how do I refer to the append function declared above?
}
toString()
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以引入一个函数引用变量,如下所示:
val f = ::append
并打电话f而不是append,但还有另一种方式吗?