From 46229636fc05a1cfd174f4fff7150eb06fe49f4d Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Tue, 18 Apr 2017 16:01:41 +0700 Subject: [PATCH] stdlib: Add plus/minus extensions for Set --- .../main/kotlin/kotlin/collections/Sets.kt | 124 +++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/runtime/src/main/kotlin/kotlin/collections/Sets.kt b/runtime/src/main/kotlin/kotlin/collections/Sets.kt index 1153802e88e..49e96622c1a 100644 --- a/runtime/src/main/kotlin/kotlin/collections/Sets.kt +++ b/runtime/src/main/kotlin/kotlin/collections/Sets.kt @@ -64,11 +64,11 @@ public fun linkedSetOf(vararg elements: T): LinkedHashSet = elements.toCo @kotlin.internal.InlineOnly public inline fun Set?.orEmpty(): Set = this ?: emptySet() +// TODO: Add SingletonSet class /** * Returns an immutable set containing only the specified object [element]. - * The returned set is serializable. */ -//public fun setOf(element: T): Set = java.util.Collections.singleton(element) +public fun setOf(element: T): Set = hashSetOf(element) /** @@ -87,3 +87,123 @@ internal fun Set.optimizeReadOnlySet() = when (size) { 1 -> setOf(iterator().next()) else -> this } + +/** + * Returns a set containing all elements of the original set except the given [element]. + * + * The returned set preserves the element iteration order of the original set. + */ +public operator fun Set.minus(element: T): Set { + val result = LinkedHashSet(mapCapacity(size)) + var removed = false + return this.filterTo(result) { if (!removed && it == element) { removed = true; false } else true } +} + +/** + * Returns a set containing all elements of the original set except the elements contained in the given [elements] array. + * + * The returned set preserves the element iteration order of the original set. + */ +public operator fun Set.minus(elements: Array): Set { + val result = LinkedHashSet(this) + result.removeAll(elements) + return result +} + +/** + * Returns a set containing all elements of the original set except the elements contained in the given [elements] collection. + * + * The returned set preserves the element iteration order of the original set. + */ +public operator fun Set.minus(elements: Iterable): Set { + val other = elements.convertToSetForSetOperationWith(this) + if (other.isEmpty()) + return this.toSet() + if (other is Set) + return this.filterNotTo(LinkedHashSet()) { it in other } + val result = LinkedHashSet(this) + result.removeAll(other) + return result +} + +/** + * Returns a set containing all elements of the original set except the elements contained in the given [elements] sequence. + * + * The returned set preserves the element iteration order of the original set. + */ +public operator fun Set.minus(elements: Sequence): Set { + val result = LinkedHashSet(this) + result.removeAll(elements) + return result +} + +/** + * Returns a set containing all elements of the original set except the given [element]. + * + * The returned set preserves the element iteration order of the original set. + */ +@kotlin.internal.InlineOnly +public inline fun Set.minusElement(element: T): Set { + return minus(element) +} + +/** + * Returns a set containing all elements of the original set and then the given [element] if it isn't already in this set. + * + * The returned set preserves the element iteration order of the original set. + */ +public operator fun Set.plus(element: T): Set { + val result = LinkedHashSet(mapCapacity(size + 1)) + result.addAll(this) + result.add(element) + return result +} + +/** + * Returns a set containing all elements of the original set and the given [elements] array, + * which aren't already in this set. + * + * The returned set preserves the element iteration order of the original set. + */ +public operator fun Set.plus(elements: Array): Set { + val result = LinkedHashSet(mapCapacity(this.size + elements.size)) + result.addAll(this) + result.addAll(elements) + return result +} + +/** + * Returns a set containing all elements of the original set and the given [elements] collection, + * which aren't already in this set. + * The returned set preserves the element iteration order of the original set. + */ +public operator fun Set.plus(elements: Iterable): Set { + val result = LinkedHashSet(mapCapacity(elements.collectionSizeOrNull()?.let { this.size + it } ?: this.size * 2)) + result.addAll(this) + result.addAll(elements) + return result +} + +/** + * Returns a set containing all elements of the original set and the given [elements] sequence, + * which aren't already in this set. + * + * The returned set preserves the element iteration order of the original set. + */ +public operator fun Set.plus(elements: Sequence): Set { + val result = LinkedHashSet(mapCapacity(this.size * 2)) + result.addAll(this) + result.addAll(elements) + return result +} + +/** + * Returns a set containing all elements of the original set and then the given [element] if it isn't already in this set. + * + * The returned set preserves the element iteration order of the original set. + */ +@kotlin.internal.InlineOnly +public inline fun Set.plusElement(element: T): Set { + return plus(element) +} +