I do not have exact answer how to do it in Java, but I have close answer how to do it Python. You should be able to replicate this solution using web3j from Python web3.py logic.
ERC-20 tokens do not maintain an iterable list of current token holders, the used
mapping type allows you only to check for a known address - balance. To get a list of all token holders, you need to process this offline and build it yourself from blockchain data.
I have created a standalone tool which collects ERC-20 token holders and transactions to SQLite database
Take a token contract address
Iterate over all
Transfer events for token using
eth_getLogs JSON-RPC API
Build a local database of these events
Allow you to use SQL to query any account balance on any point of time (block num)
The tool maintains a local SQLite database. The subsequent command runs scan the new blocks, since last run, and write the new transactions to the database. Exporting this from SQL based on a timestamp should be quite easy.
You can find the command line application execution example how to build the token holder database here
The core Python logic is here.
There are some quirks here and there: for example detecting mint / creation event for some tokens is not straightforward. Thus, you will may negative balance on the account receiving initial total supply if you rely on
Transfer event only.