package std.util import java.util.* /** Returns the size of the collection */ val Collection<*>.size : Int get() = size() /** Returns true if this collection is empty */ val Collection<*>.empty : Boolean get() = isEmpty() /** Returns a new ArrayList with a variable number of initial elements */ inline fun arrayList(vararg values: T) : ArrayList = values.to(ArrayList(values.size)) /** Returns a new LinkedList with a variable number of initial elements */ inline fun linkedList(vararg values: T) : LinkedList = values.to(LinkedList()) /** Returns a new HashSet with a variable number of initial elements */ inline fun hashSet(vararg values: T) : HashSet = values.to(HashSet(values.size)) /** Returns true if any elements in the collection match the given predicate */ inline fun java.lang.Iterable.any(predicate: (T)-> Boolean) : Boolean { for (elem in this) { if (predicate(elem)) { return true } } return false } /** Returns true if all elements in the collection match the given predicate */ inline fun java.lang.Iterable.all(predicate: (T)-> Boolean) : Boolean { for (elem in this) { if (!predicate(elem)) { return false } } return true } /** Returns the first item in the collection which matches the given predicate or null if none matched */ inline fun java.lang.Iterable.find(predicate: (T)-> Boolean) : T? { for (elem in this) { if (predicate(elem)) return elem } return null } /** Returns a new collection containing all elements in this collection which match the given predicate */ inline fun java.lang.Iterable.filter(result: Collection = ArrayList(), predicate: (T)-> Boolean) : Collection { for (elem in this) { if (predicate(elem)) result.add(elem) } return result } /** * Returns the result of transforming each item in the collection to a one or more values which * are concatenated together into a single collection */ inline fun java.lang.Iterable.flatMap(result: Collection = ArrayList(), transform: (T)-> Collection) : Collection { for (elem in this) { val coll = transform(elem) if (coll != null) { for (r in coll) { result.add(r) } } } return result } /** Performs the given operation on each element inside the collection */ inline fun java.lang.Iterable.foreach(operation: (element: T) -> Unit) { for (elem in this) operation(elem) } /** Creates a String from all the elements in the collection, using the seperator between them and using the given prefix and postfix if supplied */ inline fun java.lang.Iterable.join(separator: String, prefix: String = "", postfix: String = "") : String { val buffer = StringBuilder(prefix) var first = true for (elem in this) { if (first) first = false else buffer.append(separator) buffer.append(elem) } buffer.append(postfix) return buffer.toString().sure() } /** Returns a new collection containing the results of applying the given function to each element in this collection */ inline fun java.lang.Iterable.map(result: Collection = ArrayList(), transform : (T) -> R) : Collection { for (item in this) result.add(transform(item)) return result } /** Returns a new collection containing the results of applying the given function to each element in this collection */ inline fun java.util.Collection.map(result: Collection = ArrayList(this.size), transform : (T) -> R) : Collection { for (item in this) result.add(transform(item)) return result } // TODO would be nice to not have to write extension methods for Array, Iterable and Iterator inline fun > Array.to(result: C) : C { for (elem in this) result.add(elem) return result } inline fun > java.lang.Iterable.to(result: C) : C { for (elem in this) result.add(elem) return result } inline fun java.lang.Iterable.toLinkedList() : LinkedList = this.to(LinkedList()) inline fun java.lang.Iterable.toList() : List = this.to(ArrayList()) inline fun java.lang.Iterable.toSet() : Set = this.to(HashSet()) inline fun > java.lang.Iterable.toSortedList() : List = toList().sort() inline fun > java.lang.Iterable.toSortedList(comparator: java.util.Comparator) : List = toList().sort(comparator) /** TODO figure out necessary variance/generics ninja stuff... :) inline fun java.lang.Iterable.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List { val answer = this.toList() answer.sort(transform) return answer } */ inline fun java.util.Collection.toArray() : Array { val answer = Array(this.size) var idx = 0 for (elem in this) answer[idx++] = elem return answer as Array } // List APIs inline fun > List.sort() : List { Collections.sort(this) return this } inline fun > List.sort(comparator: java.util.Comparator) : List { Collections.sort(this, comparator) return this } /** TODO figure out necessary variance/generics ninja stuff... :) inline fun List.sort(transform: fun(T) : java.lang.Comparable<*>) : List { val comparator = java.util.Comparator() { fun compare(o1: T, o2: T): Int { val v1 = transform(o1) val v2 = transform(o2) if (v1 == v2) { return 0 } else { return v1.compareTo(v2) } } } answer.sort(comparator) } */ val List.head : T? get() = this.get(0) val List.first : T? get() = this.head val List.tail : T? get() { val s = this.size return if (s > 0) this.get(s - 1) else null } val List.last : T? get() = this.tail // Map APIs /** Returns the size of the map */ /* TODO get redeclaration errors val Map<*,*>.size : Int get() = size() */ /** Returns true if this map is empty */ /* TODO get redeclaration errors val Map<*,*>.empty : Boolean get() = isEmpty() */ /** Returns the value for the given key or returns the result of the defaultValue function if there was no entry for the given key */ inline fun java.util.Map.getOrElse(key: K, defaultValue: ()-> V) : V { val current = this.get(key) if (current != null) { return current } else { return defaultValue() } } /** Returns the value for the given key or the result of the defaultValue function is put into the map for the given value and returned */ inline fun java.util.Map.getOrElseUpdate(key: K, defaultValue: ()-> V) : V { val current = this.get(key) if (current != null) { return current } else { val answer = defaultValue() this.put(key, answer) return answer } }