Bom dia, estou fazendo um trabalho que seria pegar o tom de cada pixel de uma imagem cinza, comparar com várias imagens menores (também escala cinza) disponibilizadas em uma pasta e fazer uma espécie de mosaico substituindo os pixels pelas imagens de tons equivalentes.
Pensando em melhorar um pouco a performace, já que são mais de 2700 imagens/ladrilhos, eu implementei a interface compareble em uma classe Ladrilho, e esta, possui propriedades como imagem (BufferedImage), tonalidadeMédia e número de vezes que repetiu (o problema estipula max. 10 vzs por ladrilho). E utilizo o Collection.sort() para organizar meus ladrilhos(que estão num ArrayList) pela média. Previamente eu peguei a tonalidade de todos os pixels da imagem base e o tomMax e min para não carregar ladrilhos desnecessários.
Para achar uma imagem/ladrilho adequada eu tenho uma variável que guarda o index da ultima imagem retornada(uma vez que esteja ordenado, imagens tendem a ter tonalidades próximas, então começar do index 0 seria mais demorado), e com essa variável eu adiciono 1 caso o pixel tenha tonalidade maior que o ladrilho do index atual, ou -1 caso o ladrilho tenha tonalidade maior que a do pixel. Caso a imagem não tenha sido utilizada mais de 10 vezes, eu a retorno, senão à removo da lista.
Meu problema está em achar um jeito de sair do while quando todas as imagens com tons adequados foram removidas(por serem utilizadas 10x). Se alguém tiver uma ideia fico agradecido 
Desculpem pelo texto grande xD
qualquer ideia de performace com relação ao trabalho também é bem vindo 
Aqui um codigo +/- do que seria…
public Ladrilho buscarLadrilho(int pixel, int margemErro) {
int media = 0;
Ladrilho lad;
do {
lad = BaseImagens.getLadrilho(posicaoUltimaBusca);
if (lad.getNumVezesUtilizado() < 10) {
media = lad.getMediaRGB();
if (pixel > media && posicaoUltimaBusca < BaseImagens.getLadrilhos().size() - 1) {
posicaoUltimaBusca++;
} else if (posicaoUltimaBusca > 0) {
posicaoUltimaBusca--;
} else {
return null;
}
} else {
BaseImagens.removeLadrilho(posicaoUltimaBusca);
}
} while (Math.abs(media - pixel) > margemErro);
lad.addNumVezesUtilizado();
return BaseImagens.getLadrilho(posicaoUltimaBusca);
}