Estou tentando filtrar um recurso e excluir alguns elementos com base em um campo. Para excluir, tenho um conjunto (que contém um ID que precisa ser excluído) e uma lista (contém vários intervalos de IDs que precisam ser excluídos). Eu escrevi a lógica abaixo e não estou satisfeito com a segunda lógica do filtro. Existe alguma maneira melhor de fazê-lo com o Java 8? Eu preciso fazer o mesmo para incluir intervalos também.
Set<String> extensionsToExclude = new HashSet<>(Arrays.asList("20","25","60","900"));
List<String> rangesToExclude = new ArrayList<>(Arrays.asList("1-10","20-25","50-70","1000-1000000"));
return directoryRecords.stream()
.filter((directoryRecord) -> !extensionsToExclude.contains(directoryRecord.getExtensionNumber()))
.filter((directoryRecord -> {
Boolean include = true;
for(String s : rangesToExclude) {
String [] rangeArray = s.split("-");
Integer extension = Integer.parseInt(directoryRecord.getExtensionNumber());
if(extension <= Integer.parseInt(rangeArray[0]) && extension >= Integer.parseInt(rangeArray[1])) {
include = false;
}
}
return include;
}))
.collect(Collectors.toList());
Obrigado :)
java
lambda
java-8
java-stream
Yadvendra Rathore
fonte
fonte
Boolean
objetos quando você só precisa de umboolean
valor. Embora aqui, a variávelinclude
seja totalmente obsoleta. Quando a única alteração possível é detrue
parafalse
, você pode substituirinclude = false;
por,return false;
pois o resultado final já foi determinado. Em seguida, oreturn include;
no final pode ser substituídoreturn true;
e a declaração da variável removida. E comodirectoryRecord
nunca muda no loop, você pode mover oInteger extension = Integer.parseInt(directoryRecord.getExtensionNumber());
antes do loop (e mudarInteger
paraint
).Respostas:
Eu faria isso com uma
Range
classe personalizada , algo como:O que tornará possível algo assim:
Pessoalmente, acho seu primeiro filtro bom o suficiente para ser preservado como está.
fonte
noneMatch
quando estamos falandorangesToExclude
? E suponho que poderia haver uma solução ainda mais elegante com umaTreeSet<Range>
…Eu sugeriria similar à resposta de ernest_k com
Range
.Mas nessa abordagem, você pode usar a coleção para criar
List<Range>
(isso"20"
pode ser tratado como"20-20"
) e alterar a condição do filtro para usar a negaçãoanyMatch
.ATUALIZAR
A criação de
List<Range> ranges
pode ser alterada para remover pontos doSet<String> extensionsToExclude
intervalo criado a partir deList<String> rangesToExclud
. Em seguida, intervalos desnecessários não serão criados.fonte
você pode fazer uma pausa antecipada se a condição do intervalo for verdadeira, em vez de esperar que todas as entradas sejam avaliadas.
caso contrário, basta retornar false após o loop for.
fonte