Java 8似乎生成了表示lambda表达式的类.例如,代码:
Runnable r = app::doStuff;
Run Code Online (Sandbox Code Playgroud)
大致表现为:
// $FF: synthetic class
final class App$$Lambda$1 implements Runnable {
private final App arg$1;
private App$$Lambda$1(App var1) {
this.arg$1 = var1;
}
private static Runnable get$Lambda(App var0) {
return new App$$Lambda$1(var0);
}
public void run() {
this.arg$1.doStuff();
}
}
Run Code Online (Sandbox Code Playgroud)
据我了解,代码是在运行时生成的.现在,假设有人想将代码注入run上述类的方法中.迄今为止的实验产生了NoClassDefFound和VerifyError:
java.lang.NoClassDefFoundError: App$$Lambda$2
at App$$Lambda$2/1329552164.run(Unknown Source)
at App.main(App.java:9)
Caused by: java.lang.ClassNotFoundException: App$$Lambda$2
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 2 more
Run Code Online (Sandbox Code Playgroud)
这是针对:
$ java -version
java …Run Code Online (Sandbox Code Playgroud) 在研究Java8 Streams时,我遇到了以下代码片段:
Predicate<? super String> predicate = s -> s.startsWith("g");
Run Code Online (Sandbox Code Playgroud)
由于泛型参数是下限,我认为这不会编译.我看到它的方式,如果一个Object是String的超类型,那么传入一个Object类型应该会破坏它,因为Object没有startsWith()函数.但是,我很惊讶地看到它没有任何问题.
更进一步,当我调整谓词采取上限:
<? extends String>,
Run Code Online (Sandbox Code Playgroud)
它不会编译.
我以为我理解了上限和下限的含义,但显然,我错过了一些东西.任何人都可以帮助解释为什么下限与这个lambda一起工作?
我有兴趣确定一种方法,该方法返回排除另一个列表中元素的元素列表.
例如
List<Integer> multiplesOfThree = ... // 3,6,9,12 etc
List<Integer> evens = ... // 2,4,6,8 etc
List<Integer> others = multiplesOfThree.except(evens) // should return a list of elements that are not in the other list
Run Code Online (Sandbox Code Playgroud)
你怎么做到这一点?我找到了一种有点笨拙且难以阅读的方法....
multiplesOfThree.stream()
.filter(intval -> evens.stream().noneMatch(even -> even.intValue() == intval.intValue()))
Run Code Online (Sandbox Code Playgroud) 我想使用基于另一个方法引用的方法引用.这很难解释,所以我给你举个例子:
Person.java
public class Person{
Person sibling;
int age;
public Person(int age){
this.age = age;
}
public void setSibling(Person p){
this.sibling = p;
}
public Person getSibling(){
return sibling;
}
public int getAge(){
return age;
}
}
Run Code Online (Sandbox Code Playgroud)
给定一个Persons 列表,我想使用方法引用来获取其兄弟年龄的列表.我知道这可以这样做:
roster.stream().map(p -> p.getSibling().getAge()).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有可能更像这样:
roster.stream().map(Person::getSibling::getAge).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
在这个例子中它并不是非常有用,我只是想知道什么是可能的.
Function接口的许多lambda都采用了这种形式
t -> {
// do something to t
return t;
}
Run Code Online (Sandbox Code Playgroud)
我经常这样做,所以我已经为此编写了一个方法.
static <T> Function<T, T> consumeThenReturn(Consumer<T> consumer) {
return t -> {
consumer.accept(t);
return t;
};
}
Run Code Online (Sandbox Code Playgroud)
这使我能够做到这样的非常好的事情:
IntStream.rangeClosed('A', 'Z')
.mapToObj(a -> (char) a)
.collect(Collectors.collectingAndThen(Collectors.toList(), consumeThenReturn(Collections::shuffle)))
.forEach(System.out::print);
Run Code Online (Sandbox Code Playgroud)
还有另一种方法可以在不依赖我自己的方法的情况下进行这样的转换吗?我错过的新API中有什么东西会让我的方法变得多余吗?
我有几种CompletionStage方法可以链接.问题是第一个的结果将决定是否应该执行下一个.现在,实现这一目标的唯一方法似乎是将"特殊"参数传递给next,CompletionStage因此它不会执行完整的代码.例如:
public enum SomeResult {
RESULT_1,
RESULT_2,
RESULT_3
}
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
return CompletableFuture.supplyAsync(() -> {
// loooooong operation
if (someCondition)
return validValue;
else
return null;
}).thenCompose(result -> {
if (result != null)
return someMethodThatReturnsACompletionStage(result);
else
return CompletableFuture.completedFuture(null);
}).thenApply(result -> {
if (result == null)
return ChainingResult.RESULT_1;
else if (result.someCondition())
return ChainingResult.RESULT_2;
else
return ChainingResult.RESULT_3;
});
}
Run Code Online (Sandbox Code Playgroud)
因为整个代码依赖于第一个代码someCondition(如果它是false结果将是RESULT_1,如果不是那么整个代码应该被执行)这个结构对我来说看起来有点难看.有没有办法决定是否应该执行2nd(thenCompose(...))和3rd(thenApply(...))方法?
所以让我假设我有一个Arraylist对象Animal.该类的对象是这样的:
class Animal{
String Name;//for example "Dog"
String Color
}
Run Code Online (Sandbox Code Playgroud)
我想要做的,是数不同的颜色在每个动物中存在多少ArrayList,把他们在一个Map<String,Integer>地方String是名称和Integer对不同颜色的数量.
例如,如果有4只黑狗和1只白色等同于放在地图上
map.put("Dog",2);
Run Code Online (Sandbox Code Playgroud)
我知道它可以使用,Stream但我不知道如何.
Java 8 中引入了函数接口,用于在 Java 中实现函数式编程。它代表一个函数,它接受一个参数并产生一个结果。它易于练习和阅读,但我仍在努力了解它的好处,而不仅仅是让它看起来很酷。例如,
Function<Integer, Double> half = a -> a / 2.0;
Function<Double, Double> triple = b -> b * 3;
double result = half.andThen(triple).apply(8);
Run Code Online (Sandbox Code Playgroud)
可以转换为标准方法,如
private Double half(int a) {
return a / 2.0;
}
private Double triple (int b) {
return b * 3;
}
double result = triple(half(8));
Run Code Online (Sandbox Code Playgroud)
那么使用Function有什么好处呢?既然提到了函数式编程,那么 Java 中的函数式编程究竟是什么以及它可以带来的好处呢?它会不会像这样受益:
Stream?基本上,我很想知道,在什么情况下我们更喜欢使用函数而不是普通方法?是否有无法或难以使用的用例,或使用正常方法转换的用例?
我正在使用 io.github.resilience4j。1.6.1 版本一切正常,但升级到 1.7.1 版本后,我的应用程序无法运行。请在下面找到我的代码更改。
我的 pom.xml 依赖项
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-core</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.7.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这是 application.propertes 的更改
resilience4j.circuitbreaker.configs.default.registerHealthIndicator=true
resilience4j.circuitbreaker.configs.default.slidingWindowSize= 10
resilience4j.circuitbreaker.configs.default.minimumNumberOfCalls=5
resilience4j.circuitbreaker.configs.default.permittedNumberOfCallsInHalfOpenState= 3
resilience4j.circuitbreaker.configs.default.automaticTransitionFromOpenToHalfOpenEnabled=true
resilience4j.circuitbreaker.configs.default.waitDurationInOpenState=5s
resilience4j.circuitbreaker.configs.default.failureRateThreshold=50
resilience4j.circuitbreaker.configs.default.eventConsumerBufferSize=10
resilience4j.circuitbreaker.configs.shared.slidingWindowSize=100
resilience4j.circuitbreaker.configs.shared.permittedNumberOfCallsInHalfOpenState=30
resilience4j.circuitbreaker.configs.shared.waitDurationInOpenState=1s
resilience4j.circuitbreaker.configs.shared.failureRateThreshold=50
resilience4j.circuitbreaker.configs.shared.eventConsumerBufferSize=10
resilience4j.circuitbreaker.instances.profile.registerHealthIndicator=true
resilience4j.circuitbreaker.instances.profile.slidingWindowSize=10
resilience4j.circuitbreaker.instances.profile.minimumNumberOfCalls=10
resilience4j.circuitbreaker.instances.profile.permittedNumberOfCallsInHalfOpenState=3
resilience4j.circuitbreaker.instances.profile.waitDurationInOpenState=5s
resilience4j.circuitbreaker.instances.profile.failureRateThreshold=50
resilience4j.circuitbreaker.instances.profile.eventConsumerBufferSize=10
resilience4j.retry.configs.default.maxAttempts=3
resilience4j.retry.configs.default.waitDuration=100
resilience4j.retry.instances.profile.baseConfig=default
resilience4j.bulkhead.configs.default.maxConcurrentCalls=30
resilience4j.bulkhead.configs.instances.profile.maxWaitDuration=10ms
resilience4j.bulkhead.configs.instances.profile.maxConcurrentCalls=20
resilience4j.thread-pool-bulkhead.configs.default.maxThreadPoolSize=4
resilience4j.thread-pool-bulkhead.configs.default.coreThreadPoolSize=2
resilience4j.thread-pool-bulkhead.configs.default.queueCapacity=2
resilience4j.thread-pool-bulkhead.instances.profile.maxThreadPoolSize=1
resilience4j.thread-pool-bulkhead.instances.profile.coreThreadPoolSize=1
resilience4j.thread-pool-bulkhead.instances.profile.queueCapacity=1
resilience4j.ratelimiter.configs.default.registerHealthIndicator=false
resilience4j.ratelimiter.configs.default.limitForPeriod=10
resilience4j.ratelimiter.configs.default.limitRefreshPeriod=1s
resilience4j.ratelimiter.configs.default.timeoutDuration=0
resilience4j.ratelimiter.configs.default.eventConsumerBufferSize=100
resilience4j.timelimiter.configs.default.cancelRunningFuture=false
resilience4j.timelimiter.configs.default.timeoutDuration=2s
resilience4j.timelimiter.instances.profile.baseConfig=default
Run Code Online (Sandbox Code Playgroud)
这是控制器 API 的更改
private static final String PROFILE="profile";
@GetMapping("/{programType}/profile")
@AdobeIOAuthentication
@RateLimiter(name = PROFILE)
@TimeLimiter(name = PROFILE)
@CircuitBreaker(name …Run Code Online (Sandbox Code Playgroud) java-8 ×10
java ×8
java-stream ×3
lambda ×3
asynchronous ×1
bytecode ×1
generics ×1
predicate ×1
resilience4j ×1
spring-boot ×1