Explain all, any, and none on Kotlin collections, including their behavior on an empty collection and the no-argument overloads.
answer
- Empty: all=true, any=false, none=true (vacuous truth)
- all/any/none short-circuit
- any() = not empty, none() = empty (no-arg)
- all{p} == none{!p}
- Prefer any{} over count{}>0
basics
~20 sall checks every element matches a condition, any checks at least one does, none checks zero do. On an empty list: all is true, any is false, none is true. any() and none() with no argument just test whether the collection has elements.
solid answer
~40 sall { p } returns true only if every element satisfies the predicate; any { p } true if at least one does; none { p } true if zero do. Crucially they short-circuit. On an empty collection the results follow vacuous-truth logic: all → true (no counterexample), any → false (no witness), none → true. The no-argument overloads are about emptiness: any() means 'is not empty', none() means 'is empty', isEmpty()/isNotEmpty() are clearer equivalents. Identities to remember: all { p } == none { !p }, and any { p } == !none { p }. These read better than count { } > 0 and may short-circuit, avoiding a full traversal.
code
kotlin · 10 linesval users = listOf<User>()
// vacuous truth on empty
println(users.all { it.isAdmin }) // true
println(users.any { it.isAdmin }) // false
println(users.none { it.isAdmin }) // true
// no-arg overloads describe emptiness
println(users.any()) // false → collection is empty
println(users.none()) // true → collection is emptygo deeper
Knows all/any/none test predicates and roughly what each means.
Recalls the vacuous-truth empty results and the no-arg emptiness overloads.
Cites the short-circuit behavior and the De Morgan identities, and prefers them over count-based checks.
Reasons about short-circuiting cost on lazy/expensive sources and writes self-documenting quantifier-based validation logic.
## The three quantifiers These are boolean **quantifier** functions over a predicate `(T) -> Boolean`: - `all { p }` — **universal**: true iff *every* element satisfies `p`. - `any { p }` — **existential**: true iff *at least one* element satisfies `p`. - `none { p }` — true iff *no* element satisfies `p`. ## Short-circuiting All three stop as soon as the answer is decided: - `all` stops at the first element that **fails** `p` (returns false). - `any` stops at the first element that **passes** `p` (returns true). - `none` stops at the first element that **passes** `p` (returns false). This matters for performance on large or lazy `Sequence` sources. ## Empty-collection semantics (vacuous truth) This is a classic interview trap: | Function | Empty result | Reason | |----------|--------------|--------| | `all { }` | **true** | No element violates the predicate. | | `any { }` | **false** | No element satisfies it. | | `none { }` | **true** | No element satisfies it. | ## No-argument overloads - `any()` → `true` if the collection has **any** elements (i.e. not empty). - `none()` → `true` if the collection is **empty**. - There is **no** no-arg `all()`. Prefer `isEmpty()` / `isNotEmpty()` for readability; they express intent directly. ## Useful identities ```kotlin list.all { p(it) } == list.none { !p(it) } list.any { p(it) } == !list.none { p(it) } list.none { p(it) } == list.all { !p(it) } ``` ## Idiom Don't write `list.count { it.active } > 0`; write `list.any { it.active }` — clearer and short-circuits. ```kotlin val xs = listOf(2, 4, 6) xs.all { it % 2 == 0 } // true xs.any { it > 5 } // true (short-circuits at 6) xs.none { it < 0 } // true emptyList<Int>().all { it > 0 } // true (vacuous) emptyList<Int>().any() // false (no-arg = not empty?) emptyList<Int>().none() // true (no-arg = empty?) ```
- Why does all { } return true for an empty collection?Vacuous truth: 'all elements satisfy p' fails only if some element violates p. With no elements there is no counterexample, so it is true.
- What is the difference between any() and isNotEmpty()?Behaviorally none for a plain collection — both report non-emptiness. isNotEmpty() expresses intent more clearly; any() is handy when chaining on a Sequence.
On an empty room: 'everyone is wearing red' is trivially true (no one to disprove it), 'someone is wearing red' is false (no one at all).
saying these in an interview costs you the question
- Saying all { } is false on an empty collection
- Saying any { } is true on an empty collection
- Not knowing the no-arg any()/none() overloads
- Using count { } > 0 instead of any { } (no short-circuit, less readable)