Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

183
Visualizações
Refactoring two almost identical methods

I have two almost identical methods which filter the list and returns the filtered result. Their algorithm is identical, the difference is that the first function returns the most frequent element and the second returns the least frequent:

private static List<List<Character>> filter(List<List<Character>> lines, int charIndex) {
        List<List<Character>> result = copyList(lines);

        List<List<Character>> startWith0 = new ArrayList<>();
        List<List<Character>> startWith1 = new ArrayList<>();

        for(int i = 0; i < result.size(); i++) {
            List<Character> currentLine = result.get(i);
            if (currentLine.get(charIndex) == '1') {
                startWith1.add(currentLine);
            } else if (currentLine.get(charIndex) == '0') {
                startWith0.add(currentLine);
            }
        }

        if (startWith1.size() > startWith0.size() ||
        startWith1.size() == startWith0.size()) {
            return startWith1;
        } else {
            return startWith0;
        }
    }

The end of the second function looks like this:

if (startWith1.size() > startWith0.size() ||
        startWith1.size() == startWith0.size()) {
        return startWith0;
} else {
        return startWith1;
}

I think that this duplication of code is not a good program design but I don't see the good way to divide the first part of the function and second one into the different methods.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

You have a few options.

  1. Helper method

Make a helper method (it is private, its name starts with the method it is a helper for, though in this case, as its a helper for 2, that might be a little tricky), which does all the work, and has a state parameter that indicates how to do the last part. In this case, your state param can simply be a boolean. For other such situations, often an enum (which you can also write in the same source file, and declare as private) is more appropriate.

This helper would end in something like:

boolean winner = startWith1.size() < startWith0.size();
return most == winner ? startWith1 : startWith0;

And your current filter method becomes a one-liner:

public List<Character> filterMost(List<List<Character>> lines, int charIdx) {
  return filter(lines, charIdx, true);
}

private List<Character> filter(List<List<Character>> lines, int charIdx, boolean most) {
 ...
}
  1. Lambdas

You can pass a function that selects what to do based on an input of the 2 lists. Effectively it's the same as the first answer (still involves helper methods), but instead of writing the different code paths in the helper, you write them in the actual methods (passing them to the helper). It's more complicated but can result in easier to maintain code. Generally, 'shorter, less complex' code always wins from 'longer, more complex, but theoretically more maintainable' code, so in this case I doubt this is the right move. However, in cases where there are more states and the different part is more involved, this can be the better answer. Looks like this:

public List<Character> filterMost(List<List<Character>> lines, int charIdx) {
 ...
}

public List<Character> filterLeast(List<List<Character>> lines, int charIdx) {
  return filter(lines, charIdx, (list0, list1) -> {
    if (list0.size() < list1.size()) return list0;
    return list1;
  };
}

private List<Character> filter(List<List<Character>> lines, int charIdx, BinaryOperator<List<Character>> op) {
 ...

return op.apply(startWith0, startWith1);
}
over 4 years ago · Santiago Trujillo Relatório

0

IMHO you can factor out the loop which is filling the two ArrayLists and - of course - give both methods selfexplaining names like filerMostFrequent/filterLeastFrequent or so:

    private static List<List<Character>> filerMostFrequent(List<List<Character>> lines, int charIndex) {
        List<List<Character>> result = copyList(lines);

        List<List<Character>> startWith0 = new ArrayList<>();
        List<List<Character>> startWith1 = new ArrayList<>();

        filter(charIndex, result, startWith0, startWith1);

        if (startWith1.size() > startWith0.size() ||
        startWith1.size() == startWith0.size()) {
            return startWith1;
        } else {
            return startWith0;
        }
    }

    private static List<List<Character>> filterLeastFrequent (List<List<Character>> lines, int charIndex) {
        List<List<Character>> result = copyList(lines);

        List<List<Character>> startWith0 = new ArrayList<>();
        List<List<Character>> startWith1 = new ArrayList<>();

        filter(charIndex, result, startWith0, startWith1);

        if (startWith1.size() > startWith0.size() ||
                startWith1.size() == startWith0.size()) {
                return startWith0;
        } else {
                return startWith1;
        }
    }

    private static void filter(int charIndex, List<List<Character>> result, 
            List<List<Character>> startWith0,
            List<List<Character>> startWith1) {
        
        for(int i = 0; i < result.size(); i++) {
            List<Character> currentLine = result.get(i);
            if (currentLine.get(charIndex) == '1') {
                startWith1.add(currentLine);
            } else if (currentLine.get(charIndex) == '0') {
                startWith0.add(currentLine);
            }
        }
    }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda