我对scala试图通过将等效的java更改为scala来理解这一点非常新,以便我更好地理解。
如何将java 8地图,过滤器和流转换为scala?
我有以下java 8代码,我试图转换为Scala:
public Set<String> getValidUsages(String itemId, long sNo, Date timeOfAccess) {
Set<String> itemSet = Sets.newHashSet();
TestWindows testWindows = items.get(itemId).getTestWindows();
final boolean isTV = existsEligibleTestWindow(testWindows.getTV(), timeOfAccess);
if (isTV) {
itemSet.add(TV);
} else {
final boolean isCableUseable = existsEligibleTestWindow(testWindows.getCableUse(), timeOfAccess);
final boolean isWifi = existsEligibleTestWindow(testWindows.getWifi(), timeOfAccess);
if (isCableUseable || isWifi) {
itemSet.add(MOVIE);
}
}
if (testWindows.getUsageIds() != null) {
itemSet.addAll(testWindows.getUsageIds()
.entrySet()
.stream()
.filter(entry -> existsEligibleTestWindow(entry.getValue(), timeOfAccess))
.map(Map.Entry::getKey)
.collect(Collectors.toSet()));
}
return itemSet;
}
private boolean existsEligibleTestWindow(List<TestWindow> windows, Date timeOfAccess) {
if (windows != null) {
return windows.stream()
.filter(w -> withinDateRange(timeOfAccess, w))
.findAny()
.isPresent();
}
return false;
}
private boolean withinDateRange(Date toCheck, TestWindow window) {
return toCheck.after(window.getStartTime()) && toCheck.before(window.getEndTime());
}
我试过了:
def withinDateRange(toCheck: Date, window: TestWindow): Boolean = {
toCheck.after( window.getStartTime ) && toCheck.before( window.getEndTime )
}
def getValidUsages(itemId: String, sNo: Long, timeOfAccess: Date): Set[String] = {
var itemSet = Sets.newHashSet()
val testWindows = items.value(itemId).getTestWindows
val isTV = existsEligibleTestWindow(testWindows.get(0).getTV, timeOfAccess)
if (isTV) {
itemSet += TV
} else {
val isCableUseable = existsEligibleTestWindow(testWindows.get(0).getCableUse, timeOfAccess)
val isWifi = existsEligibleTestWindow(testWindows.get(0).getWifi, timeOfAccess)
if (isCableUseable || isWifi) {
itemSet += MOVIE
}
}
if (testWindows.get(0).getUsageIds != null) {
itemSet.addAll(testWindows.get(0).getUsageIds.entrySet().stream()
.filter((x) => existsEligibleTestWindow(x._2, timeOfAccess)).map(x => Map.Entry._1 )
.collect(Collectors.toSet()))
}
itemSet
}
def existsEligibleConsumptionWindow(windows: List[ConsumptionWindow], timeOfAccess: Date): Boolean = {
if (windows != null) {
return windows.exists((x) => withinDateRange(timeOfAccess, x))
}
false
}
但是在进行过滤和流时会出错。有人能指出方向吗?任何参考?我在getValidUsages上遇到错误:
compile error “cannot resolve reference project with such signature
答案 0 :(得分:0)
这有点难以回答,因为我不熟悉您使用的某些类型。但是,如果我猜有以下类型:
trait Window {
def getStartTime: LocalDate
def getEndTime: LocalDate
}
trait TestWindows extends Window {
def getTV: List[Window]
def getCableUse: List[Window]
def getWifi: List[Window]
def getUsageIds: Map[String, List[Window]]
}
然后你可以这样做:
def withinDateRange(toCheck: LocalDate)(window: Window): Boolean =
window.getStartTime.isBefore(toCheck) && window.getEndTime.isAfter(toCheck)
// Nothing should ever be null in Scala. If it's possible you don't have any ConsumptionWindows you should either
// model it as an empty list or an Option[List[ConsumptionWindow]]
def existsEligibleTestWindow(windows: List[Window],
timeOfAccess: LocalDate): Boolean =
windows.exists(withinDateRange(timeOfAccess))
def getValidUsages(testWindows: TestWindows, timeOfAccess: LocalDate): Set[String] = {
val isTV = existsEligibleTestWindow(testWindows.getTV, timeOfAccess)
val isCableUse = existsEligibleTestWindow(testWindows.getCableUse, timeOfAccess)
val isWifi = existsEligibleTestWindow(testWindows.getWifi, timeOfAccess)
val tvOrMovie: Option[String] = if (isTV) Some("TV")
else if (isCableUse || isWifi) Some("MOVIE")
else None
val byUsageId = testWindows.getUsageIds.collect { case (key, windows) if existsEligibleTestWindow(windows, timeOfAccess) => key }.toSet
tvOrMovie.toSet ++ byUsageId
}
在您的原始代码中,可能会有一些items
值,但在上面我假设您在TestWindows testWindows = items.get(itemId).getTestWindows()
函数之外执行getValidUsages
。
我的示例根本不使用Java结构,只使用scala核心集合。另一个主要区别是我使用的是不可变数据结构,我认为这种结构更容易理解并且通常更安全。
有些注意事项:
1)当调用None时,Option.toSet操作结果为空集。
2)有一个用于withinDateRange
方法的函数currying的例子。
3)我显然不知道你的原始类型做了什么,不得不猜测相关部分。
答案 1 :(得分:0)
问题似乎是你在Scala中使用Java类型,同时依赖于scala的map&amp;过滤操作。这有其自身的麻烦,但如果你首先将列表/集合转换为Scala's collections(警告,Scala类型默认是不可变的),那么你应该能够只使用map / filter操作而不必调用java的stream()
方法。
答案 2 :(得分:-1)
l <- lapply(lapply(m$x$calls, function(x) x[[2]]), function(x) x[4][[1]])
layerIds <- unlist(l[sapply(l, function(x) {class(x) != "list" & !is.null(x)})])
g <- lapply(lapply(m$x$calls, function(x) x[[2]]), function(x) x[5][[1]])
groupIds <- unlist(g[sapply(g, function(x) {class(x) != "list" & !is.null(x)})])
祝你好运:)