I've touched on this topic in many of replies this week, and I won't put in links to all of them, but you can find them if you want
I'll start with which features I'd likely have omitted, as that's an easier question. I'd almost certainly have omitted modules, as the cost-benefit ratio seems
way out of whack. The costs, in terms of conceptual surface area, and engineering effort at ever level of the platform from VM to language to libraries to tools, are high, and the benefits are small. I've had several tool developers complain to me about how much trouble modules had caused them, and I've had senior developers at several companies tell me that they'd studied modules extensively and come to the conclusion that they would be of little or know benefit to their companies. I honestly don't know why the Java platform architects chose to pursue this feature. If I had to guess, I'd say it's because they studied it for a long time (since before I left Sun), and this produced a mindset where they were willing to throw good money after the bad. This is, of course, just speculation on my part.
While default methods in interfaces have real benefits, I believe they are likely too dangerous in their present form (see Item 21: "Design interfaces for posterity" for details). I would have insisted on a safer design, and I would have omitted the feature in the unlikely event that we couldn't have come up with one. Also I would have refactored the "downstream collector" concept, so that it leveraged the
Stream API rather that duplicating major portions of it.
As for features that I would have added, they would have been small, evolutionary steps with high power-to-weight ratios. I would have added collection literals several releases back, extended the for-each loop to work on strings (and other CharSequences), and on the libraries front added immutable variants of
EnumSet and
EnumMap. I believe that Java 7's "Project Coin" was one of the most successful additions to the platform in "recent" years, and I'd pursue further changes along those lines. I'd provide literals for the primitive types that don't have them. Also on the libraries front, I'd make
Stream extend
Iterable at the first opportunity, to allow for better interoperability between streaming and iteration and, in particular, to allow for-each construct to be used on streams. See "Item 47: Prefer Collection to Stream as a return type" for more on this topic.
The lists in this post are by no means complete. They're just what comes to mind right now. I hope I've said enough that you understand my general approach.