使用ListBuffer获取列表元素时遇空列表问题求助
嘿,这个问题的核心是类型不匹配导致的,咱们一步步拆解来看:
为什么两种写法结果天差地别?
第一种写法里,val list2 = List(args(0), args(1)),因为args本身是Array[String],所以list2的类型是List[String]。当你调用x.contains(y)时,y是String类型,刚好匹配String.contains(CharSequence)的方法(String本身就实现了CharSequence接口),所以能正确判断x是否包含y这个子串,最终得到符合预期的List("abc","mnp")。
而第二种写法里,你用了new ListBuffer[Any]来存储参数——虽然你存进去的是String,但ListBuffer的类型被指定成了Any,转成List后list2的类型就变成了List[Any]。这时候y的类型是Any,而String.contains有两个重载方法:
- 一个接受
Char类型参数 - 一个接受
CharSequence类型参数
编译器没办法确定Any类型的y是CharSequence,所以会优先尝试匹配接受Char的版本。但你的参数是"bc"和"mn",都是完整字符串而非单个字符,所以这个判断永远返回false,最终filter后自然得到空列表。
怎么修正?
有两种简单可行的办法:
方法1:指定ListBuffer的正确类型(推荐)
把ListBuffer[Any]改成ListBuffer[String],这样转成List后类型和第一种写法完全一致,就能正常工作了:
val list1 = List("abc", "def", "mnp") val ipList1 = new ListBuffer[String] // 明确指定String类型 for(i <- 0 to 1){ ipList1 += args(i) } val list2 = ipList1.toList println(list2) val header1 = list1.filter(x => list2.exists(y => x.contains(y))) println(header1)
方法2:显式转换类型(不推荐,存在类型安全风险)
如果一定要保留ListBuffer[Any]的写法,可以在调用contains时把y强制转成String:
val header1 = list1.filter(x => list2.exists(y => x.contains(y.asInstanceOf[String])))
不过这种方法有隐患,如果list2里混入了非String类型的元素,运行时会抛出异常,所以更推荐第一种方法。
内容的提问来源于stack exchange,提问作者Hannah

