Are you asking permission to keep building on code that you suspect is inefficient?
Hobby projects only need to run on the target machines you want them to. If that's just your computer at home and you're happy with your code's performance then great. If you want to distribute it to other people, you can't guarantee that everyone has a modern screaming machine at home. You could just arbitrarily say that you need X for minimum specs to run your game. But then you're probably cutting out a lot of people from playing your game. And if your game is something that's on a more simple order of things... well I can tell you that I'm not upgrading my machine to play a beginning developer's platformer or tetris clone. But if that doesn't bother you then focus on areas that you want to focus on for the time being (that may sound judgmental but actually I mean that in a sincere way... code what you want to code).
However, I don't think your language choice is an excuse for the technique that you're using. You can use classes in Java so I see no reason you couldn't do method #2. Even without classes you could probably figure something out.
In any case, ideally you want to load each image file once because it takes quite a bit of time to read an image from disk and then (as I understand) to also load that image to a texture on the GPU. Doing both of these per frame of animation sounds like you're going to have some very slow animations. (unless I misunderstand the technique you're using).
In my projects I have currently have a sprite class, an animation class, and an actor class. The sprite class is where I load the image data to when the program is first initialized. The animation class is where I keep co-ordinates, widths, and frame durations. And the actor class (and other sub-classes) would be where I keep stuff like a character's position in the game world (I currently use it for items as well). The actor class also has a pointer to the sprite object that it's going to be using and its own copy of animation data in an array (one array element per animation) and one variable for what animation is being used and one for what the current frame is. I used to have a pointer to animation data that I loaded up once per sprite but I found that I sometimes wanted to manipulate that data on a per actor basis.
When it's time to do the draw for an actor, I look at the animation data for the current animation and frame for the co-ordinates and widths to use. I pass all this stuff to my paint function and the character is blt to the screen. The actual code that I have for all this is crap. It's a real mess of spaghetti and the above description isn't quite accurate. Each of those classes I've mentioned I've had in a variety of configurations and combinations and coupled together in all sorts of ways. It's taken time and experimentation to sort it out to what it is now.
I suspect that you may not have a way currently to determine co-ordinates and widths of frames for your sprites. It takes some time and work to get something going to store the data as well as to determine what the data actually is. As my code is currently, I often manually hard-code data for every animation despite having created my own tool to create files to load the same data from. It's not really fun but it's part of development.
tldr;
Just try writing a simple test project or two to test out different techniques for getting images to the screen. See what you're happy with and go from there.
Good luck.