该Optional.or方法是在Java 9中添加的.这是方法签名
public Optional<T> or?(Supplier<? extends Optional<? extends T>> supplier)
Run Code Online (Sandbox Code Playgroud)
为什么是的类型参数Supplier回吐? extends Optional,而不是仅仅Optional因为Optional是最后的类?
该Optional.flatMap方法也是如此.这是Java 8的变化.
在Java 8中,它被Function<? super T, Optional<U>> mapper改为Function<? super T,?? extends Optional<? extends U>>Java 9.
Java不允许在供应商中使用最终变量,因为它可能没有被初始化,而是在"(this)"之前.变量使它编译并运行正常.
此外,在分配变量之前调用此类供应商会导致NullPointerException而不是编译器错误,并在调用之后按预期运行.
这种行为是在某处描述的吗?
我正在使用OpenJDK 1.8.0_151.
例:
import java.util.function.Supplier;
class Example {
final String str;
Supplier<Integer> test1 = () -> str.length(); // DOES NOT COMPILE
Supplier<Integer> test2 = () -> this.str.length(); // DOES NOT COMPILE
Supplier<Integer> test3 = () -> (this.str).length(); // DOES NOT COMPILE
Supplier<Integer> test4 = () -> (this).str.length(); // OK
Example(String str) {
System.out.println(test4.get()); // NullPointerException
this.str = str;
System.out.println(test4.get()); // OK
}
}
---
javac Example.java
Example.java:7: error: variable str might not have been initialized
Supplier<Integer> test1 …Run Code Online (Sandbox Code Playgroud) 我知道关于这个问题有很多问题,即使是最近的问题,但我仍然无法解决一件事。考虑以下功能接口:
@FunctionalInterface
interface PersonInterface {
String getName();
}
Run Code Online (Sandbox Code Playgroud)
而这个实现:
class Person implements PersonInterface {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
如果查看这些线程1和2,我希望输出以下代码"Bob",而不抛出a,NullPointerException因为据我了解,在创建我的Supplier时,它捕获了Person实例。
Person p = new Person("Bob");
Supplier<String> f = p::getName;
p = null;
System.out.println(f.get());
Run Code Online (Sandbox Code Playgroud)
并正确输出 "Bob"
现在我不明白的是为什么下面的代码也没有输出"Bob"?
Person p = new Person("Bob"); …Run Code Online (Sandbox Code Playgroud) 寻找如何使用Java lambda函数,以便Consumer可以处理供应商提供的所有对象,并摆脱显式while循环和null检查.
我有一个数据库的String键供应商,我想使用Consumer来处理每个键.
Supplier<String> keyGen = new SimpleKeySupplier(keyPrefix, numKeys);
Consumer<String> consumer = (String key) -> System.out.println("key="+key);
Run Code Online (Sandbox Code Playgroud)
我想consumer处理由提供的每个密钥,keyGen并尝试以下.它有效,但我确信必须有一种更简洁的方法来使用lambda函数来简化这一过程.
// Test that the correct keys have been populated.
Supplier<String> keyGen = new SimpleKeySupplier(keyPrefix, NumKeys);
String k = keyGen.get();
while(k != null) {
consumer.accept(k);
k = keyGen.get();
}
Run Code Online (Sandbox Code Playgroud)
SimpleKeySupplier工作,简化版本如下:
import java.util.function.Supplier;
public class SimpleKeySupplier implements Supplier<String> {
private final String keyPrefix;
private final int numToGenerate;
private int numGenerated;
public SimpleKeySupplier(String keyPrefix, int numRecs) {
this.keyPrefix …Run Code Online (Sandbox Code Playgroud) 我们都知道Optional<T>有一种方法T get(),为什么它没有实现Supplier<T>呢?
如果碰巧没有理由,如果Oracle要将它实现到Java的未来版本中会不会破坏任何先前的代码?
AssertionsJUnit 5 中的类允许传递Supplier<String>as a messageSupplier,这是一个提供消息文本以在测试失败时报告的对象。
例如assertEquals:
public static void assertEquals?( char expected,
char actual,
Supplier<String> messageSupplier )
Run Code Online (Sandbox Code Playgroud)
我想知道这样一个供应商的实际用途可能是什么,特别是在单元测试的背景下。
我可以想象可能会对字符串进行本地化,尽管当受众是开发项目的成员时,本地化似乎有点奇怪。
? 传递这样的消息提供者而不是硬编码消息字符串还有其他实际用途吗?
我所看到的BiConsumer,BiPredicate,BiFunction但不能BiSupplier或类似。我尝试了下面的代码,但有一个异常说:
“在 BiSupplier 中发现的多个非覆盖抽象方法”。
@FunctionalInterface
public interface BiSupplier<T, R> {
/**
* Gets a first.
*
* @return a first
*/
T getFirst();
/**
* Gets a second.
*
* @return a second
*/
R getSecond();
}
Run Code Online (Sandbox Code Playgroud)
可以请一些人帮我解决这个问题。
我有两个函数调用 Employee 和 Address DAO 类,我在其中检查员工姓名或地址是否已被使用
为了使检查和抛出异常通用,我创建了以下通用函数
checkOrElseThrow在CommonUtil.java
public static <R, C, T extends Throwable> R checkOrElseThrow(R rtn, C chk, Supplier<? extends T> ex) throws T
{
if (chk != null)
{
throw ex.get();
}
return rtn;
}
Run Code Online (Sandbox Code Playgroud)
上面的通用函数在EmployeeDAO.java和AddressDAO.java 中被调用,如下所示
checkAndReturnEmployee在EmployeeDAO.java
public Employee checkAndReturnEmployee(Employee employee) {
return checkOrElseThrow(
employee,
employee.getAddressName(),
() -> new EntityNotFoundException("Employee already in use for another address"));
}
Run Code Online (Sandbox Code Playgroud)
checkAndReturnAddress在AddressDAO.java
public Address checkAndReturnAddress(Address address) {
return checkOrElseThrow(
address, …Run Code Online (Sandbox Code Playgroud) 我想让我的代码更通用。为了实现这一点,我证明了列表和供应商都是方法参数。
事实证明,reduce()在有多个可供选择的情况下,无法推断具体方法(见下面的屏幕截图)。
如何声明我想要使用的方法版本?
public BigDecimal methodCalculate(List<MyObject> list, Supplier<? extends BigDecimal> getValue) {
BigDecimal sum = list.stream()
.filter(item -> item.getPremium())
.map(item -> getValue)
.reduce(BigDecimal.ZERO, BigDecimal::add);
return sum;
}
Run Code Online (Sandbox Code Playgroud)
在下面的代码中,我尝试将info方法称为供应商.(info方法重载:一个是String,另一个是供应商.)编译器抱怨"方法info(String)不适用于参数Supplier<Double>".我的期望是通过发送供应商对象来调用info方法来获取供应商.我可以帮助理解这个错误吗?
Supplier<Double> randomSupplier = new Supplier<Double>()
{ public Double get()
{ return Math.random(); }
};
logger.info(randomSupplier); <----
Run Code Online (Sandbox Code Playgroud)