如何在Kotlin中使用LinkedHashSet插入另一个元素

时间:2019-05-10 09:53:11

标签: kotlin

我正在尝试搜索具有以下属性的集合类型:

  • 保持插入顺序
  • 不允许重复
  • 依次添加一个或多个元素

我可以创建自己的数据收集,但我不愿意。

看完kotlin中所有可用的集合后,我认为LinkedHashSet几乎满足了我的所有要求,但是不能在另一个位置或第n个位置添加元素。

是否有任何方法可以通过扩展方法或其他技巧来实现?

3 个答案:

答案 0 :(得分:0)

您可以只使用List <>或其任何实现。它保持插入顺序,您可以一个接一个地添加一个或多个元素,并且可以通过返回列表时调用.distinct()来实现“避免重复”的要求。即:

private fun fillData(): MutableList<String> {
    var dataSet: MutableList<String> = ArrayList()
    for (i in 0..10) dataSet.add("Product $i")
    dataSet.add("aaa")
    dataSet.add("aaa")
    dataSet.add("aaa")
    dataSet.add("aaa")
    dataSet.add("aaa")
    return dataSet.distinct().toMutableList()
}

此函数的结果返回一个数组,其中包含11个元素,“产品1” ..“产品10”,最后只有1个“ aaa”元素。

您可以看到List.distinct()here的文档

答案 1 :(得分:0)

据我所知,在标准库(和Java集合API)中没有这样的集合类型。

Apache commons collections但是包含您要查找的内容:ListOrderedSet

答案 2 :(得分:0)

为什么不实现完全满足您需求的自定义数据结构?

class OrderedHashSet<E> : MutableSet<E>{

    private val set = HashSet<E>()
    private val list = LinkedList<E>()

    override val size: Int
        get() = list.size

    override fun contains(element: E) = set.contains(element)

    override fun containsAll(elements: Collection<E>) = set.containsAll(elements)

    override fun isEmpty() = list.isEmpty()

    override fun iterator() = list.iterator()

    override fun add(element: E): Boolean {
        if(set.add(element)){
            list.add(element)
            return true
        }
        return false
    }

    fun add(index: Int, element: E) : Boolean {
        if(set.add(element)){
            list.add(index, element)
            return true
        }
        return false
    }

    override fun addAll(elements: Collection<E>): Boolean {
        var modified = false
        for(element in elements){
            if(add(element)){
                modified = true
            }
        }
        return modified
    }

    override fun clear() {
        set.clear()
        list.clear()
    }

    override fun remove(element: E): Boolean {
        set.remove(element)
        return list.remove(element)
    }

    override fun removeAll(elements: Collection<E>): Boolean {
        var modified = false
        for(element in elements){
            if(remove(element)){
                modified = true
            }
        }
        return modified
    }

    override fun retainAll(elements: Collection<E>): Boolean {
        set.retainAll(elements)
        return list.retainAll(elements)
    }

}