Arrays 如何使用流过滤二维阵列并将其映射到集合中

Arrays 如何使用流过滤二维阵列并将其映射到集合中,arrays,kotlin,java-stream,Arrays,Kotlin,Java Stream,我有一个2DIntArray,它代表一个游戏板,其中-1表示一个空格,一些值grater或等于0表示该单元格属于某个玩家。类似下面的内容(-1由点(.)表示) 我想得到一个集合,其中的单元格位置已经被任何玩家占据。大概是这样的: [Cell{1,0}, Cell{1,1}, ..., Cell{3,4}] 我知道第一种方法是迭代二维数组: val set = HashSet<Cell>(); for(row in 0 until HEIGHT){ for (col in 0

我有一个2D
IntArray
,它代表一个游戏板,其中-1表示一个空格,一些值grater或等于0表示该单元格属于某个玩家。类似下面的内容(-1由点(.)表示)

我想得到一个
集合
,其中的单元格位置已经被任何玩家占据。大概是这样的:

[Cell{1,0}, Cell{1,1}, ..., Cell{3,4}]
我知道第一种方法是迭代二维数组:

val set = HashSet<Cell>();
for(row in 0 until HEIGHT){
    for (col in 0 until WIDTH){
        if(board[row][col] >= 0)
            set.add(Cell(row, col))
    }
}

如果将Java流替换为范围,则这可以使Kotlin更自然一些

val cells = (0 until board.size).flatMap { row ->
    (0 until board[row].size)
            .filter { col -> board[row][col] >= 0 }.map { Cell(row, it) }
}.toSet()

首先,建议使用Kotlin标准库,而不是Java流。在Kotlin标准库中,我只需将
flatMap
替换为
flatMapTo
调用,以避免创建后来被丢弃的列表:

val set = HashSet<Cell>()
(0 until board.size).flatMapTo(set) { row ->
    (0 until board[row].size).filter { col ->
        board[row][col] >= 0
    }.map { col ->
        Cell(row, col)
    }
}
val set=HashSet()
(0到board.size)。flatMapTo(设置){行->
(0到板[row].size).过滤器{col->
线路板[行][列]>=0
}.map{col->
单元格(行、列)
}
}
如果您确实需要Java8流解决方案,请使用以下代码:

fun IntRange.stream() : Stream<Int>
    = StreamSupport.stream(spliterator(), false)

val set = (0 until board.size).stream().flatMap { row ->
    (0 until board[row].size).stream().filter { col ->
        board[row][col] >= 0
    }.map { col ->
        Cell(row, col)
    }
}.collect(Collectors.toSet())
fun IntRange.stream():流
=StreamSupport.stream(spliterator(),false)
val set=(0到board.size).stream().flatMap{row->
(0到板[row].size).stream().filter{col->
线路板[行][列]>=0
}.map{col->
单元格(行、列)
}
}.collect(收集器.toSet())
至于性能,这里给出的两种解决方案应该非常相似(不过我还没有测试过)。但是,Java8流允许您并行执行操作(请参阅)。这是使用一些线程池,为你做所有的魔术。据我所知,Kotlin不提供任何现成的并行操作,但它提供了比Java线程快得多的并行操作,但在您这方面它提供了更多的代码

val set = HashSet<Cell>()
(0 until board.size).flatMapTo(set) { row ->
    (0 until board[row].size).filter { col ->
        board[row][col] >= 0
    }.map { col ->
        Cell(row, col)
    }
}
fun IntRange.stream() : Stream<Int>
    = StreamSupport.stream(spliterator(), false)

val set = (0 until board.size).stream().flatMap { row ->
    (0 until board[row].size).stream().filter { col ->
        board[row][col] >= 0
    }.map { col ->
        Cell(row, col)
    }
}.collect(Collectors.toSet())