So, languages that have primitives like this typically are designed to be used by people who don't know much about algorithms, or simply don't want to be hassled with it, either now, or ever: they want to write code, they want it to "work", and they want to move on to something else; in essence, we are talking "scripting languages".
Languages that some look at as "real programming languages", in comparison, tend to not have syntax like this, and the reason why is that you often, either now, or at some point later, are going to care whether the data structure you just allocated is a red-black tree, a hash map, a patricia trie, or even an AVL tree (which I include mostly to make a point: there actually are situations where it is preferred to a red-black tree).
When this suddenly matters, you are in the situation where what you want to be able to do is to make a very small modification to areas of your code where you need to select a different algorithm, in order to get the different result; you don't want to be forced to rewrite half your code to use a different syntax just because it was slow (I mean, if you wanted to do that, you'd have written it in Ruby and then recoded it in C).
Therefore, you find that it is normally the case in languages like Java, C++, and Objective-C, that there are no "built-in container types", as you will never find a container type that is actually correct to use in an even fractional majority of the cases; in fact, most of the time, there isn't even a single obvious choice in these languages for what class to use: you find default implementations of multiple algorithms.
Objective-C, here, is no different from this concept: NSDictionary is just an interface, and can be implemented by numerous backends. Apple has a rather good implementation backing the default version, and even attempts to switch between algorithms as the data structure grows, but your code is always just a few identifiers away from choosing a different subclass in that collection hierarchy.