Scala实现PEM转DER证书时filter报Predicate类型不匹配错误
报错原因
BufferedReader.lines()返回的是Java 8引入的java.util.stream.Stream[String]对象,它的filter方法要求入参必须是Java标准库的java.util.function.Predicate[_ >: String]类型(Java函数式接口)。你传入的(line: String) => Boolean是Scala原生的Function1[String, Boolean]类型,在未做显式转换的情况下,编译器无法自动识别两种类型的对应关系,因此抛出类型不匹配错误。
可运行的实现方案
方案1:显式做函数类型适配
通过Scala标准库提供的Java函数转换工具,把Scala函数显式转为Java要求的Predicate实例即可,代码改动量最小:
import java.io.{BufferedReader, StringReader} import java.util.Base64 import java.util.stream.Collectors // 导入Scala函数转Java函数式接口的扩展方法 import scala.jdk.FunctionConverters._ def convertPemToDer(pem: String): Array[Byte] = { val bufferedReader = new BufferedReader(new StringReader(pem)) val encoded = bufferedReader .lines() .filter( ((line: String) => !line.startsWith("-----BEGIN") && !line.startsWith("-----END")).asJava ) .collect(Collectors.joining()) Base64.getDecoder.decode(encoded) }
方案2:改用Scala原生集合写法(推荐)
直接把Java Stream转为Scala原生集合,后续全部用Scala标准集合API操作,完全不需要处理Java和Scala的函数类型适配问题,代码更符合Scala开发习惯,出问题的概率更低:
import java.io.{BufferedReader, StringReader} import java.util.Base64 // 导入Java Stream转Scala集合的扩展方法 import scala.jdk.StreamConverters._ def convertPemToDer(pem: String): Array[Byte] = { val bufferedReader = new BufferedReader(new StringReader(pem)) val encoded = bufferedReader .lines() .toScala(LazyList) .filter(line => !line.startsWith("-----BEGIN") && !line.startsWith("-----END")) .mkString Base64.getDecoder.decode(encoded) }
注:如果你使用的是Scala 2.12及更早版本,上述
scala.jdk包下的转换方法需要引入第三方依赖scala-java8-compat,或者使用对应版本自带的JavaConverters工具类实现相同效果。
内容的提问来源于stack exchange,提问作者Random Guy
相关产品推荐
相关产品推荐

