Your problem is that any possible caching mechanism will use far more memory and processor power than you are ever likely to save.
Just think of your example - creating the String, doing the map look-up, garbage collecting the String, etc.
That's a lot more work than just creating a new Double.
The HashMap itself will use a lot of memory.
Considering the number of possible Double values are you going to expire them from the cache somehow or will it keep growing for ever?
It is somewhat telling that the natural key to use into a cache of doubles would be a "new Double" itself (almost certainly faster than the String approach).
You also need to consider equality. For example try in java:
System.out.println((1-0.9)==0.1);
The result is false as the double values generated by each half are different by a miniscule fraction. But if you get a Double from your cache would you want the same Double for (1-0.9) as for (0.1) ?
So you are opening up a massive complicated can of worms, for incredibly tiny savings (in fact you are unlikely to save, most likely you will actually slow things down and use more memory not less).
The only real way to get much better efficiency is just by using double instead of Double (although I realize that's not always possible).