新的Java 8流框架和朋友们制作了一些非常简洁的Java代码,但是我遇到了一个看似简单的情况,简单易懂.
考虑一个List<Thing> things方法Optional<Other> resolve(Thing thing).我想将Things 映射到Optional<Other>s并获得第一个Other.显而易见的解决方案是使用things.stream().flatMap(this::resolve).findFirst(),但flatMap要求您返回一个流,并且Optional没有stream()方法(或者它是Collection一个方法或提供将其转换为或以其方式查看的方法Collection).
我能想到的最好的是:
things.stream()
.map(this::resolve)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
Run Code Online (Sandbox Code Playgroud)
但这似乎是一个非常普遍的案例,似乎非常冗长.谁有更好的主意?
我一直在使用Java 8中的新Optional类型,我遇到了似乎是功能上不支持的常见操作:"orElseOptional"
考虑以下模式:
Optional<Result> resultFromServiceA = serviceA(args);
if (resultFromServiceA.isPresent) return result;
else {
Optional<Result> resultFromServiceB = serviceB(args);
if (resultFromServiceB.isPresent) return resultFromServiceB;
else return serviceC(args);
}
Run Code Online (Sandbox Code Playgroud)
这种模式有很多种形式,但归结为在一个可选项上需要一个"orElse",它接受一个生成一个新的可选项的函数,只有当前的一个不存在时才被调用.
它的实现看起来像这样:
public Optional<T> orElse(Supplier<Optional<? extends T>> otherSupplier) {
return value != null ? this : other.get();
}
Run Code Online (Sandbox Code Playgroud)
我很好奇是否有这样的方法不存在的原因,如果我只是以一种无意的方式使用Optional,以及人们提出了处理这种情况的其他方式.
我应该说,我认为涉及自定义实用程序类/方法的解决方案并不优雅,因为使用我的代码的人不一定知道它们存在.
另外,如果有人知道,这样的方法是否会包含在JDK 9中,我可以在哪里提出这样的方法?对我来说,这似乎是对API的一个相当明显的遗漏.
这似乎是一个非常基本的问题,但我搜索得很高,并且发现几乎没有提到任何地方.所以,我会在这里问一下.
在GWT中支持Java 8的新语言结构的当前计划是什么?
此外,建议的Java 8库的哪个子集用于客户端仿真?Stream API?新的日期/时间API?
最后,关于这个重要主题的讨论在哪里进行?我敢肯定,我们中有许多人愿意参与并可能为此付出努力.
Java 8测试版现在已经存在了一段时间,并且有许多文章讨论了提议的API.它应该在今年晚些时候相关,所以似乎过去的时间至少要讨论如何以及何时将非常需要的语言功能引入GWT.
如果这个问题在其他地方得到解答,或者我错过了一些与之相关的重要信息,我很抱歉.即使已经回答,这也是获取此类信息链接的好地方.谢谢!
Guava的Optional 模式非常棒,因为它有助于消除null的模糊性.transform当链的第一部分可能不存在时,该方法对于创建空安全方法链非常有用,但是当链的其他部分不存在时,该方法无用.
这个问题与Guava Optional类型有关,当转换返回另一个Optional时,它基本上要求相同的问题,但对于不同的用例,我认为这可能不是Optional(处理错误)的预期用途.
考虑一种方法Optional<Book> findBook(String id).findBook(id).transform(Book.getName)按预期工作.如果找不到书,我们就会得到一本书Absent<String>,如果有书就找到了Present<String>.
在中间方法可能返回null/ 的常见情况下absent(),似乎没有一种优雅的方式来链接调用.例如,假设Book有一个方法Optional<Publisher> getPublisher(),我们希望得到一本书的出版商出版的所有书籍.似乎是自然语法findBook(id).transform(Book.getPublisher).transform(Publisher.getPublishedBooks),但这会失败,因为transform(Publisher.getPublishedBooks)调用实际上会返回一个Optional<Optional<Publisher>>.
在一个类似transform()的方法上Optional接受一个返回一个的函数似乎是合理的Optional.它的行为与当前的实现完全相同,只是它不会将函数的结果包装在Optional中.实现(for Present)可能是:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
return function.apply(reference);
}
Run Code Online (Sandbox Code Playgroud)
实施Absent方式不变transform:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
checkNotNull(function);
return Optional.absent();
} …Run Code Online (Sandbox Code Playgroud) TL; DR:似乎类型别名的类型参数(例如type T[X<:Serializable])在作为变量,参数和其他情况引用时不强制执行它们的约束.但是,案例类会为其参数正确实施边界.
考虑设计用于表示泛型类型子集的类型别名.例如,让我们说我想要一个类型的Serializable事物列表:
scala> type SerializableList[T <: Serializable] = List[T]
defined type alias SerializableList
Run Code Online (Sandbox Code Playgroud)
现在说我想要一个带有这些参数的case类:
scala> case class NetworkDataCC(things: SerializableList[_])
<console>:9: error: type arguments [_$1] do not conform to type SerializableList's type parameter bounds [T <: Serializable]
case class NetworkDataCC(things: SerializableList[_])
Run Code Online (Sandbox Code Playgroud)
嗯,这不起作用.Scala(恼人地)不带有类型的参数边界,但它很容易修复:
scala> case class NetworkDataCC(things: SerializableList[_ <: Serializable])
defined class NetworkDataCC
Run Code Online (Sandbox Code Playgroud)
好的.看起来不错.现在,如果我只想要一个带有这些东西的常规类,但我再次忘记显式声明类型边界.我期待一个错误:
scala> class NetworkData(val things: SerializableList[_])
defined class NetworkData
Run Code Online (Sandbox Code Playgroud)
等一下.没有错误......呵呵.
那么,现在我能做到这一点?
scala> new NetworkData(List(1))
res3: NetworkData = NetworkData@e344ad3
Run Code Online (Sandbox Code Playgroud)
嗯,这似乎很破碎.案例类,当然可以正常工作(因为声明了限制):
scala> NetworkDataCC(List(1))
<console>:11: error: …Run Code Online (Sandbox Code Playgroud) 我想通过使用host属性从另一个指令向一个元素添加一个指令,但是似乎没有办法引用另一个指令.
@Directive({
selector: '[one]',
host: { '[two]': '"some-value"' }
// How can I reference DirectiveTwo here?
})
export class DirectiveOne { }
@Directive({
selector: '[two]'
})
export class DirectiveTwo { }
Run Code Online (Sandbox Code Playgroud)
执行此操作时,我得到标准"无法绑定到'两个',因为它不是已知的本机属性"错误.
引用和使用另一个指令的正确方法是什么?
我对three.js和3d编程很新,所以这似乎是一个非常简单的问题.理想情况下,我希望答案可以帮助我理解基本原则.
我有一个对象需要在另一个点(原点,在这种情况下为了简单起见)"指向",这可以通过该Object3D.lookAt(point)功能轻松完成.这很好地指向了物体的Z轴.
我还想looker围绕其Z轴旋转我的对象,称为其X轴通常指向另一个对象,refObj.我知道X轴不能直接指向,refObj除非该物体与原点形成直角.我想的X轴looker为位于由形成的平面origin,refObj并且looker,可图示如下:

进行旋转的最简单方法似乎是修改looker.rotation.z,但我不知道如何计算值应该是什么.
一般来说,我想要一个lookAt函数的扩展版本,它采用X轴定向的第二个坐标.像这样的东西:
function lookAtAndOrient(objectToAdjust, pointToLookAt, pointToOrientXTowards)
{
// First we look at the pointToLookAt
objectToAdjust.lookAt(pointToLookAt);
// Then we rotate the object
objectToAdjust.rotation.z = ??;
}
Run Code Online (Sandbox Code Playgroud)
我正在编写一些Angular2模板,这些模板具有不同容器的重复部分.在这种情况下,如果事物已分组并且启用了多节模式,则视图可能会更改.请原谅长长的例子,但是这样的话:
<template [ngIf]="isCategoryGrouped">
<div *ngFor="#categories of categories">
<div>{{ categories.category.name }}</div>
<div *ngFor="#thing of categories.things">
<label *ngIf="isMultiSelectMode">
<input type="checkbox" (change)="updateThingSelection(thing, $event)" />
<img [src]="thing.image" /> {{ thing.name }}
</label>
<a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode">
<img [src]="thing.image" /> {{ thing.name }}
</a>
</div>
</div>
</template>
<template [ngIf]="! isCategoryGrouped">
<div *ngFor="#thing of things">
<label *ngIf="isMultiSelectMode">
<input type="checkbox" (change)="updateThingSelection(thing, $event)" />
<img [src]="thing.image" /> {{ thing.name }}
</label>
<a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode">
<img [src]="thing.image" /> {{ thing.name }}
</a>
</div>
</template> …Run Code Online (Sandbox Code Playgroud) 作为一名也参与其中的Scala开发人员GWT,我欢迎加入OptionalGuava.
我们最常见的用例之一Optional是从方法中返回可选值(如Guava的Optional类的答案所示).
在scala中,我经常编写如下代码:
def someExpensiveOperation(params: Type): Option[ResultType] = ...
someExpensiveOperation(params).foreach({ val =>
doSomethingWithVal (val)
})
Run Code Online (Sandbox Code Playgroud)
番石榴的选择似乎不允许比这样的东西更优雅:
Optional<MyType> optionalResponse = someExpensiveOperation(params);
if (optionalResponse.isPresent()) {
doSomethingWithVal(optionalResponse.get())
}
Run Code Online (Sandbox Code Playgroud)
局部变量是多余的,它需要重复一个可以抽象的模式(the if (optional.isPresent()) { doSomethingWith(optional.get()) }).
另一种选择是调用返回Optional两次的方法:
if (someExpensiveOperation(params).isPresent()) {
doSomethingWithVal(someExpensiveOperation(params).get())
}
Run Code Online (Sandbox Code Playgroud)
但这显然是不可取的,因为它不必要地多次调用昂贵的操作.
我很好奇其他人是如何处理这种非常常见的情况的(也许是通过写一个静态的实用方法,比如<T>useIfPresent(Optional<T> val, Closure<? super T> closure)?)或者是否有人找到了更优雅的解决方案.
此外,如果有人知道为什么一个方法Optional.foreach(Closure<? super T> closure)(但希望更好的名字)被省略,我会很好奇听到理由.
似乎有一个限制,你不能PartialFunction在类构造函数中使用文字:
scala> case class X(a: PartialFunction[Any, Any]) { def this() = this({case x => x}) }
<console>:7: error: Implementation restriction: <$anon: Any => Any> requires premature access to class X.
case class X(a: PartialFunction[Any, Any]) { def this() = this({ case x => x}) }
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是为什么部分函数文字需要访问"this".我的第二个问题/观察是在Scala REPL中,再次运行相同的代码会导致REPL崩溃:
scala> case class X(a: PartialFunction[Any, Any]) { def this() = this({ case x => x}) }
java.lang.NullPointerException
at scala.tools.nsc.Global$Run.compileLate(Global.scala:1595)
at scala.tools.nsc.GlobalSymbolLoaders.compileLate(GlobalSymbolLoaders.scala:29)
at scala.tools.nsc.symtab.SymbolLoaders$SourcefileLoader.doComplete(SymbolLoaders.scala:369)
...
Run Code Online (Sandbox Code Playgroud)
最后,这个问题有一个很好的解决方法吗?