Cascades are pretty elegant. They allow you to chain methods together that were never intended to be chained. Dart is smart enough to know that all these consecutive lines of code are operating on the same object. Let's pick apart the numbers example:
final numbers = [342, 23423, 53, 232, 534]
..insert(0, 10)
..sort((a, b) => a.compareTo(b));
Both the insert and sort methods are void functions. Declaring these objects with cascades simply allows you to remove the call to the numbers object:
final numbers = [342, 23423, 53, 232, 534];
numbers.insert(0, 10);
numbers.sort((a, b) => a.compareTo(b));
With the cascade operator, you can merge unrelated statements in a simple fluent chain of function calls.
In our example, UrlBuilder is just a plain old Dart object.
Without the cascade operator, we would have to write the same builder code like this:
final url = UrlBuilder();
url.scheme = 'https';
url.host = 'dart.dev';
url.routes = ['guides', 'language', 'language-tour#cascade-notation-'];
But with cascades, that code can now be simplified, like so:
final url = UrlBuilder()
..scheme = 'https'
..host = 'dart.dev'
..routes = ['guides', 'language', 'language-tour#cascade-notation-'];
Notice that this was accomplished without changing a single line in our class.