当前位置: 首页 > 知识库问答 >
问题:

在Java8中是否有Scala的等价物?

郎聪
2023-03-14

就像Java 8中的Java.util.optional (在某种程度上)与Scala的option[T]类型等价一样,是否存在与Scala的或者[L,R]等价的类型?

共有1个答案

荆炳
2023-03-14

没有或者类型是Java ;8,所以您需要自己创建一个或使用一些第三方库。

您可以使用新的optional类型构建这样的功能(但请阅读到此答案的末尾):

final class Either<L,R>
{
    public static <L,R> Either<L,R> left(L value) {
        return new Either<>(Optional.of(value), Optional.empty());
    }
    public static <L,R> Either<L,R> right(R value) {
        return new Either<>(Optional.empty(), Optional.of(value));
    }
    private final Optional<L> left;
    private final Optional<R> right;
    private Either(Optional<L> l, Optional<R> r) {
      left=l;
      right=r;
    }
    public <T> T map(
        Function<? super L, ? extends T> lFunc,
        Function<? super R, ? extends T> rFunc)
    {
        return left.<T>map(lFunc).orElseGet(()->right.map(rFunc).get());
    }
    public <T> Either<T,R> mapLeft(Function<? super L, ? extends T> lFunc)
    {
        return new Either<>(left.map(lFunc),right);
    }
    public <T> Either<L,T> mapRight(Function<? super R, ? extends T> rFunc)
    {
        return new Either<>(left, right.map(rFunc));
    }
    public void apply(Consumer<? super L> lFunc, Consumer<? super R> rFunc)
    {
        left.ifPresent(lFunc);
        right.ifPresent(rFunc);
    }
}

示例用例:

new Random().ints(20, 0, 2).mapToObj(i -> (Either<String,Integer>)(i==0?
  Either.left("left value (String)"):
  Either.right(42)))
.forEach(either->either.apply(
  left ->{ System.out.println("received left value: "+left.substring(11));},
  right->{ System.out.println("received right value: 0x"+Integer.toHexString(right));}
));
abstract class Either<L,R>
{
    public static <L,R> Either<L,R> left(L value) {
        return new Either<L,R>() {
            @Override public <T> T map(Function<? super L, ? extends T> lFunc,
                                       Function<? super R, ? extends T> rFunc) {
                return lFunc.apply(value);
            }
        };
    }
    public static <L,R> Either<L,R> right(R value) {
        return new Either<L,R>() {
            @Override public <T> T map(Function<? super L, ? extends T> lFunc,
                                       Function<? super R, ? extends T> rFunc) {
                return rFunc.apply(value);
            }

        };
    }
    private Either() {}
    public abstract <T> T map(
      Function<? super L, ? extends T> lFunc, Function<? super R, ? extends T> rFunc);

    public <T> Either<T,R> mapLeft(Function<? super L, ? extends T> lFunc) {
        return this.<Either<T,R>>map(t -> left(lFunc.apply(t)), t -> (Either<T,R>)this);
    }
    public <T> Either<L,T> mapRight(Function<? super R, ? extends T> lFunc) {
        return this.<Either<L,T>>map(t -> (Either<L,T>)this, t -> right(lFunc.apply(t)));
    }
    public void apply(Consumer<? super L> lFunc, Consumer<? super R> rFunc) {
        map(consume(lFunc), consume(rFunc));
    }
    private <T> Function<T,Void> consume(Consumer<T> c) {
        return t -> { c.accept(t); return null; };
    }
}

只需在两个工厂方法的开头插入objects.requireNonNull(value),就可以很容易地将其改为严格拒绝null。同样,添加对空任一项的支持也是可以想象的。

 类似资料:
  • 我正在尝试根据一个条件筛选一个列表。有没有一个替代的方法来中断Java8流,我可以用它来停止过滤? 举个例子:假设我有下面的列表。 如何在流中使用“break”?

  • Java7引入了MethodHandle类,用于动态执行给定类的方法。据我所知,在JDK的Android端口上没有这样的东西。除了使用标准的反射类之外,是否有任何解决方法可以用来绕过这个问题?

  • 我在Spark Java API项目中编写了一个mapToPair函数。我需要有一个类似于Scala None的功能,所以对于一个特定的地图,我可能不返回任何东西(Scala中没有) 例如,运行上述代码总是返回一个正的计数值,而不是0。

  • 问题内容: 我正在努力寻找一种方法,以根据谓词在流的开头跳过某些元素。 像这样: 那相当于Scala 。 问题答案: 这种操作不是s 的预期用例,因为它并入了元素之间的依赖关系。因此,该解决方案可能看起来不太好,因为您必须为谓词引入一个全状态变量: 请注意,与您的示例相比,该条件必须颠倒。 当然,您可以在方法中隐藏令人讨厌的细节: 一个更复杂,但更清洁,可能更有效的方法是深入研究金属,即界面: 可

  • 我最近回答了一个问题,关于当和是指向不同对象/数组的指针时,在C中执行

  • 不建议将引导程序直接用于React,因为引导程序的JavaScript可能会直接改变DOM,从而干扰React的虚拟DOM系统。关于角度(2)也可以这样说吗?