Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java堆栈选项不可用?_Java_Optional_Language Design - Fatal编程技术网

为什么Java堆栈选项不可用?

为什么Java堆栈选项不可用?,java,optional,language-design,Java,Optional,Language Design,我通常对Java语言的设计非常满意,但今天我遇到了一个奇怪的设计选择。 我不知道有哪个平台可以建议对9或10版的Java语言进行更改,因此我在这里写这篇文章 使用Optionals,如果值为null,您可以更好地控制行为 今天,我将流中的一个值映射到一个可选的。 我真的很惊讶,findFirst然后给了我一个Optional,而不仅仅是Optional 选择选项的意义何在? Optional<Optional<T>> => Optional<T> Op

我通常对Java语言的设计非常满意,但今天我遇到了一个奇怪的设计选择。 我不知道有哪个平台可以建议对9或10版的Java语言进行更改,因此我在这里写这篇文章


使用Optionals,如果值为
null
,您可以更好地控制行为

今天,我将流中的一个值映射到一个
可选的
。 我真的很惊讶,
findFirst
然后给了我一个
Optional
,而不仅仅是
Optional

选择
选项的意义何在?

Optional<Optional<T>> => Optional<T>
Optional.of(Optional.of("")) => Optional.of("")
对于Java9和Streams,这可以通过
.flatMap(可选::stream)
解决,但这只是一个解决方法和样板代码

如果Optionals通常不会堆叠并且总是平铺,不是更好吗?

Optional<Optional<T>> => Optional<T>
Optional.of(Optional.of("")) => Optional.of("")
此外,如果您正在使用optionals,您只对对象感兴趣。因此,如果您试图获取对象,则始终必须双重获取并检查可选项

if(optionalOfOptional.isPresent()) {
    optional = optionalOfOptional.get();
    if(optional.isPresent()) {
        objectOfInterest = optional.get();
    }
}
我甚至认为这是一个错误的来源,因为如果你的对象存在,你总是需要检查两个选项

if(optionalOfOptional.isPresent() && optionalOfOptional.get().isPresent()) {
    ...
}
只有检查第一个可选项,才容易导致错误

另外,为什么一开始就有一个可选的
null
?是否可以选择不使用
null


在方法层面上,这是肯定可以解决的

例如,
Optional.of
可能看起来像:

public static <T> Optional<T> of(T value) {
    return value instanceof Optional ? value : new Optional<>(value);
}
公共静态可选值(T值){
返回值instanceof Optional?值:新建可选(值);
}

在类型级别上,这可能没有那么容易。

我在其他地方谈到了这一点,它违反了
Optional
的承诺:摆脱
NullPointerException
s


因此,我认为在可选API中允许
可选
是有缺陷的设计。如果给定一个Optional,那么获取Optional实例的方法应该表现得更好。但话说回来,他们不能。如果Optional.of过载,除了一个小问题外,它们都可以完成

因为您可以有一个类型为Optional的泛型类型T,所以不能有两个Optional.of方法(一个用于Optional,一个用于T)。如果有人想出了一个
可选的
,它有时会阻止一些代码的编译。以下面的代码为例,它将无法编译

package otherCode;

public class Abc<T> {
    public static void main(String[] args) {
        Abc<B> test1 = new Abc<>();
        test1.foo(new A());
        test1.foo(new B());

        Abc<Base> test2 = new Abc<>();
        test2.foo(new A());
        test2.foo(new B());

        Abc<A> test3 = new Abc<>();
        // these two don't compile
        test3.foo(new A());
        test3.foo(new B());
    }

    public void foo(A item) {
        System.out.println("Foo");
    }

    public void foo(T item) {
        System.out.println("bar");
    }

    public static class Base {
    }

    public static class A extends Base {

    }

    public static class B extends Base {

    }
}
package-otherCode;
公共课Abc{
公共静态void main(字符串[]args){
Abc test1=新的Abc();
test1.foo(新的A());
test1.foo(新的B());
Abc测试2=新的Abc();
test2.foo(新的A());
test2.foo(新的B());
Abc test3=新的Abc();
//这两个不可编译
test3.foo(新的A());
test3.foo(新的B());
}
公开作废foo(A项){
System.out.println(“Foo”);
}
公开作废foo(T项){
系统输出打印项次(“bar”);
}
公共静态类基{
}
公共静态类A扩展了基类{
}
公共静态类B扩展了基类{
}
}
在不强制对整个语言进行语言和语法更改的情况下(禁止
可选
),自动转换并非易事

我发现,开发人员一般需要一段时间才能掌握Java8。当它第一次出现时,我会看到
Map
,而
Map
就足够了,或者我确实看到了
Optional
。我甚至看到了
Map
,而不是简单的
Map
。随着时间的推移和人们对语言的掌握,我觉得我们学会了更好地管理这些打字,并获得更明智的打字

我认为Java没有自动进行转换是不幸的,但是对于那些可能有一天需要
可选的
的可怜的灵魂,我愿意每隔一段时间使用map、flatMap、orElse和of nullable来保持我的输入正常。使用这些方法可以帮助你解决特定的难题

编辑:


我看到,OP看到了
流,不是错过了它,就是编辑了它。首先
返回一个
可选
。OP打算做什么会影响妥协。他们可以.映射流以去除内部可选项,也可以.filter&.映射流以去除空选项。一行可悲的额外代码。

禁止
可选的
根本没有意义

假设您有一个
列表
。以下列表不同:

List<Optional<T>> listA = Arrays.asList(Optional.empty());
List<Optional<T>> listB = Arrays.asList();
System.out.println(listA.stream().findFirst().isPresent()); // true
System.out.println(listB.stream().findFirst().isPresent()); // false
现在,我知道了Java不可能知道的列表中数据的含义。假设这些列表包含调用
Callable
s列表的结果。在这种情况下,我的应用程序可能有以下两个重要区别:

  • 我调用了N>0个callables,它们都返回了
    Optional.empty()
  • 我调用了零个可调用项
因此,我真的不想让语言或API假设两者之间没有区别,并将
可选
转换为
可选

由于
List.stream().findFirst()
总是返回一个
可选的
,如果不阻止我创建
列表
(或
集合
集合
哈希映射
等),就无法阻止
可选的
。因此,您基本上必须完全禁止嵌套泛型,这将是功能的重大损失


我对
Optional
的存在非常满意,因为它与语言的其余部分完全一致。如果你不喜欢它们,就不要创造它们;但不要认为这对其他人都是正确的。

描述得很好,但你的问题是,如果期权通常不会堆叠并总是平铺,不是更好吗?是基于意见的。第二个转变是