Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 从列表中高效提取文件列表<;档案>;有一张名单_Kotlin - Fatal编程技术网

Kotlin 从列表中高效提取文件列表<;档案>;有一张名单

Kotlin 从列表中高效提取文件列表<;档案>;有一张名单,kotlin,Kotlin,我有一个巨大的文件列表list(1GA)和一个小的文件名列表list,大约有20个文件名。现在,我想通过检查文件名(file.name),提取只包含其他列表(文件名列表)中的文件的文件子列表 例如: 巨大的列表[1A、2A、3A、4A、1B、2B、3B、4B、5B、6B、1C、2C、3C、4C]和文件名列表列表是[1A、2B、3C]。因此,我希望庞大的列表中的所有文件的名称都是1A和2B和3C 在Kotlin中,以Kotlin的方式做这件事最优雅、最有效的方法是什么。根据您的澄清,您根本不需要寻

我有一个巨大的文件列表
list
(1GA)和一个小的文件名列表
list
,大约有20个文件名。现在,我想通过检查文件名
(file.name)
,提取只包含其他列表(文件名列表)中的文件的文件子列表

例如: 巨大的
列表
[1A、2A、3A、4A、1B、2B、3B、4B、5B、6B、1C、2C、3C、4C]
和文件名列表
列表
[1A、2B、3C]
。因此,我希望庞大的
列表中的所有文件的名称都是
1A
2B
3C


在Kotlin中,以Kotlin的方式做这件事最优雅、最有效的方法是什么。

根据您的澄清,您根本不需要寻找子列表。(这是列表的连续部分,由例如返回)

相反,你想要的是列表。通常的方法是使用,非常简单明了:

val result = hugeList.filter{ it.name in filenameList }
这将对你庞大的列表进行线性扫描;对于每个文件,它将扫描您的文件名列表,直到找到匹配项(或文件名用尽),然后将每个匹配项追加到结果列表中

在大多数情况下,这是非常好的。但在这种情况下,性能显然是一个问题,这有两个问题:

首先,每次都需要扫描文件名列表。如果文件名很少,这可能没问题。否则,首先将其转换为一个集合(可以在固定时间内进行检查)可能更有效:

其次,它最初只为结果列表分配少量空间;随着它的不断增长,它可能需要不断重新分配更大的空间并复制元素。(例如,ArrayList每次增长50%)。因此,如果您大致知道它可能会增长多大,您可能需要预先分配一个合适容量的列表,然后再重新分配,以减少重新分配和复制。例如,如果您希望大约一半的文件匹配:

val filenameSet = filenameList.toSet()
val result: MutableList<File> = ArrayList(hugeList.size / 2)
hugeList.filterTo(result){ it.name in filenameSet }
val filenameSet=filenameList.toSet()
val结果:可变列表=ArrayList(hugeList.size/2)
hugeList.filterTo(结果){filenameSet中的it.name}

(我认为这与你可能得到的效率差不多,既不尝试并行化(参见,尽管这可能会困难得多,在这里可能不会有太大的改进),也不利用大局给你的任何机会来改变问题。)

当你说“子列表”时,你是指第一个(或者最长的)具有匹配文件名的连续文件的子序列?还是要提取每个匹配的文件?我要从庞大的列表中提取“文件”。第二个名单上的名字只是为了帮助我从庞大的名单中提取哪些文件。是的,但这并不能回答我的问题。  您希望通过检查文件名来创建一个新列表,其中包含巨大列表中的一些文件。  但是你想从庞大的列表中找到所有匹配的文件吗?  或者只是其中的一些连续匹配文件的子列表?  例如,如果您的庞大列表中有文件
[1A、2B、3A、4B、5B、6A、7B]
,并且您希望提取以
B
结尾的文件,您是否希望结果是
[2B、4B、5B、7B]
?  或者只是
[2B]
(第一个这样的子列表)?  或者
[4B,5B]
(最长的子列表)?  或者别的什么?不,我要所有的文件都在第二张名单上。例如:巨大的列表
[1A,2A,3A,4A,1B,2B,3B,4B,5B,6B,1C,2C,3C,4C]
文件名列表是
[1A,2B,3C]
。因此,我希望从庞大的列表中找到所有文件,它们的名称是
1A
2B
3C
。我只是在寻找Kotlin中最有效的方法,因为我是java开发人员,而不是Kotlin。顺便说一句,两个列表中的名字都是精确的,不是前缀也不是后缀。哇,谢谢你的回答。也许从原始大列表中删除已经找到的文件也会有所帮助?@Deksterious我不建议更新原始大列表。  如果它是用数组实现的,那么删除一个项意味着将每个后续项复制到一个上,这需要更新数组的大部分;它还会破坏引用的局部性,并失去内存缓存的好处。  (由于过滤器从第一个项目开始扫描,删除它们将使它从一个O(n)进程变成一个O(n²)进程!)……(如果它是一个链表,那么它就不会有这些缺点;但删除仍然会涉及不必要的工作。)  如果您以后不想看到这个庞大的列表,那么只需确保不保留对它的引用,并让垃圾收集器来处理它。
val filenameSet = filenameList.toSet()
val result: MutableList<File> = ArrayList(hugeList.size / 2)
hugeList.filterTo(result){ it.name in filenameSet }