【问题标题】:How to convert java 8 map, filter and streams to scala?如何将 java 8 映射、过滤器和流转换为 scala?
【发布时间】:2017-01-20 12:09:52
【问题描述】:

我对 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

【问题讨论】:

  • 错误信息是什么?
  • 您没有尝试将 java 语法转换为 scala 语法,而是尝试检查 javadoc?您不需要非延迟流。 filtermapisEmpty 直接在ListSet 上怎么样?
  • 如果您希望继续使用 java 集合,您可能需要这个:github.com/scala/…
  • @Nyavro 更新
  • 你可以使用 import scala.collection.JavaConversions._ , docs.scala-lang.org/overviews/collections/…

标签: java scala filter java-8 java-stream


【解决方案1】:
def getValidUsages(itemId: String, sNo: long, timeOfAcess: Date): Set[String] = {
  var itemSet: Set[String] = Sets.newHashSet()
  val testWindows: TestWindows = items.get(itemId).getTestWindows()
  val isTV: Boolean  = existsEligibleTestWindow(testWindows.getTV(), timeOfAccess)

  isTV match {
    case true => itemSet.add(TV)
    case false => {
      val isCableUseable: Boolean = existsEligibleTestWindow(testWindows.getCableUse(), timeOfAcess)
      val isWifi: Boolean = existsEligibleTestWindow(testWindows.getWifi(), timeOfAccess)
      if(isCableUseable || isWifi) {
        itemSet.add(MOVIE)
      }
    }
  }

  if(testWindows.getUsageIds() != null) {
    itemSet.addAll(testWindows.getUsageIds()
                .stream.
                .filter(entry => existsEligibleTestWindow(entry._2, timeOfAccess))
                .map(filteredData => Map.Entry._1)
                .collect Collectors.toSet())
  }
  itemSet
}

def existsEligibleTestWindow(windows: List[TestWindow], timeOfAcess: Date): Boolean = {
  windows match {
    case null => false
    case _ => windows.stream.filter(data => withinDateRange(timeOfAcess), data).findAny().isPresent
  }
}

祝你好运:)

【讨论】:

    【解决方案2】:

    这有点难以回答,因为我不熟悉您使用的某些类型。但如果我猜有以下类型:

    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 值,但在上面我只是假设您在 getValidUsages 函数之外执行 TestWindows testWindows = items.get(itemId).getTestWindows()

    我的示例根本不使用 java 结构,只使用 scala 核心集合。另一个主要区别是我使用不可变数据结构,我认为这更容易理解并且通常更安全。

    一些注意事项: 1) 当调用 None 时,Option.toSet 操作会导致一个空集。 2) 有一个用于withinDateRange 方法的函数柯里化示例。 3)我显然不知道你原来的类型是做什么的,不得不猜测相关的部分。

    【讨论】:

      【解决方案3】:

      问题似乎是您在 Scala 中使用 Java 类型,同时依赖于 scala 的映射和过滤操作。这有它自己的麻烦,但是如果您首先将列表/集合转换为Scala's collections(警告,Scala 类型默认是不可变的),那么您应该能够只使用映射/过滤操作而无需调用 java 的 @987654322 @方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-30
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        相关资源
        最近更新 更多