I'm building a class to work as a cache for BufferedImage or Image Objects (not sure which is best for my purposes...)
The problem is that I'm using these 'images' at various places and I need to scale them to 4 different dimensions. The sizes I have at the momment are 25x25, 50x50, 100x100 and 150x150. 25x25 & 100x100 will have to be readily available all the time (i.e. with no time delay) the other ones can have a small delay, it's ok.
What are the advantages of using Image over BufferedImage Objects?
A BufferedImageis an Image. In fact, Image itself is abstract and can never be instantiated, so in that sense you can't. In order to use an Image, you'll have to use a subclass such as BufferedImage, thus comparing BufferedImage to Image is erroneous. The proper question would be "What are the advantages of using a BufferedImage vs [any other subclass of Image]?". In your case, I'd say stick with the BufferedImage for the time being. However, if you're simply talking about how they're declared then the advantage to declaring it as an Image rather than a BufferedImage is being able to change the concrete implementation you're using later without modifying your code anywhere except the instantiation.
Should I store a single Image/BufferedImage and then scale it at time of use? (I've done this but the scaling takes a little bit of time when 100 images are used...)
Should I cache all images at all different scales? (Memory problems could arise!)
I get the idea you're looking for a magical trick that's going to solve your problem and I'm sorry to say there isn't really one. Scaling is likely to be your most time consuming task and keeping a scaled instance will speed up your program, but like you say it leaves the potential for memory problems. This is where you have to make the compromise based upon the number of images you're dealing with at one time and their size. Without knowing the details of your program's design and architecture it's hard to make any sort of judgement call about that. I will point out one thing, however, which is that if you have large images one way to potentially speed up the scaling is to keep a smaller scaled instance that you scale off of. For example, if the image is originally 3000x3000 then scaling it down to 100x100 or 25x25 is going to take some time. You can keep instances of all your 100x100, 25x25, etc. but that may take too much memory. A compromise would be to create a single 150x150 scaled instance and then use that to create your 25x25, 50x50 etc. scaled instances as necessary, only keeping the 150x150. That would cost you less memory than keeping an instance of every one, but cost you less time in scaling to 25x25 etc.