我希望能够像这样使用Stream :: flatMap
public static List<String> duplicate(String s) {
List<String> l = new ArrayList<String>();
l.add(s);
l.add(s);
return l;
}
listOfStrings.stream().flatMap(str -> duplicate(str)).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
但是我得到以下编译器错误
Test.java:25:错误:不兼容的类型:无法推断类型变量R listOfStrings.stream().flatMap(str - > duplicate(str)).collect(Collectors.toList());
(参数不匹配; lambda表达式中的错误返回类型List无法转换为Stream)
其中R,T是类型变量:R extends方法flatMap中声明的Object(Function>)T extends Interface在Interface Stream中声明的Object
在scala我可以做我认为相同的事情
scala> List(1,2,3).flatMap(duplicate(_))
res0: List[Int] = List(1, 1, 2, 2, 3, 3)
Run Code Online (Sandbox Code Playgroud)
为什么这不是java中flatMap的有效用法?
在https://try.kotlinlang.org/#/Kotlin%20Koans/Collections/FlatMap/Task.kt
它有使用flatMap和的样本map
似乎两者都在做同样的事情,是否有一个样本来显示使用flatMap和map?的区别?
数据类型:
data class Shop(val name: String, val customers: List<Customer>)
data class Customer(val name: String, val city: City, val orders: List<Order>) {
override fun toString() = "$name from ${city.name}"
}
data class Order(val products: List<Product>, val isDelivered: Boolean)
data class Product(val name: String, val price: Double) {
override fun toString() = "'$name' for $price"
}
data class City(val name: String) {
override fun toString() = name
}
Run Code Online (Sandbox Code Playgroud)
样品:
fun Shop.getCitiesCustomersAreFrom(): …Run Code Online (Sandbox Code Playgroud) 在Swift中,我试图将一系列字典拼成一个字典,即
let arrayOfDictionaries = [["key1": "value1"], ["key2": "value2"], ["key3": "value3", "key4": "value4"]]
//the end result will be:
flattenedArray = ["key1": "value1", "key2": "value2", "key3": "value3", "key4": "value4"]
Run Code Online (Sandbox Code Playgroud)
我尝试过使用flatmap,但返回结果的类型是,[(String, AnyObject)]而不是[String, Object]ie
let flattenedArray = arrayOfDictionaries.flatMap { $0 }
// type is [(String, AnyObject)]
Run Code Online (Sandbox Code Playgroud)
所以我有两个问题:
为什么返回类型[(String,AnyObject)]?括号是什么意思?
我如何达到预期的效果?
编辑:我更喜欢使用Swift的map/flatmap/reduce等功能方法而不是for-loop
我有一个 AA 类对象列表,其中包含一个日期和一个 BB 类对象列表:
data class AA(
val date: LocalDate,
val bb: List<BB>
)
@Parcelize
data class BB(
val x: Int,
val y: String,
val z: String
) : Parcelable
Run Code Online (Sandbox Code Playgroud)
我想创建一个如下所示的 List ( flatten List<AA>):
listOf(
date obj
BB obj
BB obj
date obj
BB obj
date obj
BB obj
BB obj
BB obj)
Run Code Online (Sandbox Code Playgroud)
代替:
listOf(
date obj, listOf(BB obj, BB obj)
date obj, listOf(BB obj)
date obj, listOf(BB obj, BB obj, BB obj))
Run Code Online (Sandbox Code Playgroud)
我尝试使用 flatMap,但我只设法压平了一个部分 - BB。 …
请考虑以下代码:
urls.stream()
.flatMap(url -> fetchDataFromInternet(url).stream())
.filter(...)
.findFirst()
.get();
Run Code Online (Sandbox Code Playgroud)
fetchDataFromInternet当第一个足够的时候会被叫第二个网址吗?
我尝试了一个较小的例子,看起来像预期的那样工作.即逐个处理数据但是可以依赖这种行为吗?如果没有,请.sequential()在.flatMap(...)帮助前打电话吗?
Stream.of("one", "two", "three")
.flatMap(num -> {
System.out.println("Processing " + num);
// return FetchFromInternetForNum(num).data().stream();
return Stream.of(num);
})
.peek(num -> System.out.println("Peek before filter: "+ num))
.filter(num -> num.length() > 0)
.peek(num -> System.out.println("Peek after filter: "+ num))
.forEach(num -> {
System.out.println("Done " + num);
});
Run Code Online (Sandbox Code Playgroud)
输出:
Processing one
Peek before filter: one
Peek after filter: one
Done one
Processing two
Peek before filter: two
Peek after filter: …Run Code Online (Sandbox Code Playgroud) 我一直在研究FP语言(关闭和开启)一段时间,并且使用过Scala,Haskell,F#和其他一些语言.我喜欢我所看到的并理解FP的一些基本概念(绝对没有类别理论的背景 - 所以请不要谈数学,请).
所以,给定一个类型,M[A]我们有map一个函数,A=>B并返回一个M[B].但我们也有flatMap一个功能A=>M[B]并返回一个M[B].我们也有flatten一个M[M[A]]并且返回一个M[A].
此外,许多的来源我已阅读形容flatMap为map其次flatten.
所以,鉴于这flatMap似乎相当于flatten compose map,它的目的是什么?请不要说它是支持'for comprehensions',因为这个问题确实不是Scala特有的.我不太关心语法糖,而不是我背后的概念.Haskell的bind运算符(>>=)也出现了同样的问题.我相信它们都与某些类别理论概念有关,但我不会说那种语言.
我已经看过Brian Beckman的精彩视频Do not Fear the Monad不止一次,我想我看到那flatMap是monadic组合运算符,但我从未真正看到它使用了他描述这个运算符的方式.它执行此功能吗?如果是这样,我该如何将该概念映射到flatMap?
顺便说一句,我在这个问题上写了很长的文章,上面有很多列表显示我试图深入了解其中的实验flatMap,然后遇到了这个回答我的一些问题的问题.有时我讨厌Scala暗示.他们真的可以在水中浑浊.:)
我正在阅读学习Spark书,无法理解以下对rdd转换.
rdd.flatMapValues(x => (x to 5))
Run Code Online (Sandbox Code Playgroud)
它应用于rdd {(1,2),(3,4),(3,6)}并且转换的输出是{(1,2),(1,3),(1,4),(1,5),(3,4),(3,5)}
有人可以解释一下.
给出以下作为数据类的示例:
class Country {
List<Region> regions = new ArrayList<>();
List<Region> getRegions() {
return regions;
}
}
class Region {
String getName() {
return "some name";
}
}
Run Code Online (Sandbox Code Playgroud)
假设我有一份国家清单
List<Country> countries = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
我想将这些内容传递给他们的区域及其相应的名称我想做以下事情:
countries.stream().flatMap(Country::getRegions).map(Region::getName)...
Run Code Online (Sandbox Code Playgroud)
但是,该代码无法编译,因为"getRegions"的返回值是Collection(List),而不是flatMap方法接受的Stream.但是因为我知道任何Collection都可以通过其Collection.stream()方法进行流式传输,这应该不是问题.我还是被迫写成如下:
countries.stream().flatMap(c -> c.getRegions().stream()).map(Region::getName)...
Run Code Online (Sandbox Code Playgroud)
这是(给定更丰富的背景)远比前者更不可读.
问题是,有什么理由,我错过了,因为这是那么笨重?我在我们的框架中有很多例子,我不得不采取这种方式,总是让我有一种酸味.(猜猜我只需要将Kotlin添加到我们的项目中并使用flatMap方法扩展Stream类,该方法采用Collection:p或者我?)
我们有一个Person对象的数组,每个对象都有另一个String数组,这是可选的.我们想要在我们的社会中整合汽车名称列表.
struct Person {
let name: String
let address: String
let age: Int
let income: Double
let cars: [String]?
}
let personsArray = [Person(name:"Santosh", address: "Pune, India", age:34, income: 100000.0, cars:["i20","Swift VXI"]),
Person(name: "John", address:"New York, US", age: 23, income: 150000.0, cars:["Crita", "Swift VXI"]),
Person(name:"Amit", address:"Nagpure, India", age:17, income: 200000.0, cars:nil)]
let flatmapArray = personsArray.flatMap({$0.cars})
print(flatmapArray)
Run Code Online (Sandbox Code Playgroud)
//预期结果:["i20","Swift VXI","Crita","Swift VXI"]
//结果:[["i20","Swift VXI"],["Crita","Swift VXI"]]
为什么它不给我一个字符串数组作为结果?
我在上面的代码中做了几处更改,如下面的代码,而不是"nil",我们尝试将空数组传递给第3个Person对象.
Person(name:"Amit", address:"Nagpure, India", age:17, income: 200000.0, cars:Array())
Run Code Online (Sandbox Code Playgroud)
结果是:
[["i20","Swift VXI"],["Crita","Swift VXI"],[]]
仍然不是预期的结果.
如果我从汽车数组中删除可选,如,
let cars: [String] …Run Code Online (Sandbox Code Playgroud) 使用def方法和val函数展平Vs flatMap:
我定义了一个名为toInt的def方法:
def toInt(s: String): Option[Int] = {
try {
Some(Integer.parseInt(s.trim))
} catch {
case e: Exception => None
}
}
Run Code Online (Sandbox Code Playgroud)
这个方法适用于flatten和flatMap,如下所示:
//using toInt method
val x = 1.to(5).toList
val y = List("a")
val z = x ++ y
val q = z.map(_.toString)
//using map and flatten
println(q.map(toInt).flatten)
//using flatMap
println(q.flatMap(toInt))
Run Code Online (Sandbox Code Playgroud)
现在我在函数"tooInt"中使用val定义了相同的toInt功能(如在def方法中):
val tooInt: String => Option[Int] = s => {
try {
Some(Integer.parseInt(s.trim))
} catch {
case c: Exception => None
}
}
Run Code Online (Sandbox Code Playgroud)
这正常工作与扁平化,但不如下图所示与flatMap: …
flatmap ×10
java ×3
java-8 ×3
java-stream ×3
collections ×2
kotlin ×2
scala ×2
swift ×2
android ×1
apache-spark ×1
arrays ×1
dictionary ×1
flatten ×1
ios ×1
list ×1