Tengo un bloque de instrucciones if-else en un método para el que estoy recibiendo tema complejidad ciclomática. He intentado usar sentencia switch para esto, pero todavía los restos de emisión.
if (fileName.startsWith(HwErrorsEtlConstants.MR_RAW_GRADIENT_ERRORS)) {
method1()...
} else if (fileName.startsWith(HwErrorsEtlConstants.MR_RAW_PFEI_ERRORS)) {
method2()...
} else if (fileName.startsWith(HwErrorsEtlConstants.MR_RAW_RFAMP_ERRORS)) {
method3()...
} and so on...
public static void method1(IOutputWriter writer, String fileName, InputStream fileInputStream) throws IOException {
//logic for the method
}
Editar : como usted ha mencionado que haya comprobado Exception
s que se pueden lanzar y argumentos en su método. Como Runnable
no declarar que se puede lanzar Exceptions
y aceptar también doens't cualquier parámetro que tiene que crear su propia FunctionalInterface
(haga clic aquí para ver lo que realmente son):
public interface ThrowingRunnable {
void run(IOutputWriter writer, String fileName, InputStream fileInputStream) throws IOException;
}
A continuación, sólo tiene que reemplazar Runnable
con ThrowingRunnable
en mi código propuesto anteriormente a continuación y que debe estar bien.
Puede crear una asignación de HwErrorsEtlConstants
al método específico (utiliza Java 8):
static final Map<String, Runnable> MAPPING;
static {
Map<String, Runnable> temp = new HashMap<>();
temp.put(HwErrorsEtlConstants.MR_RAW_GRADIENT_ERRORS, this::method1);
temp.put(HwErrorsEtlConstants.MR_RAW_PFEI_ERRORS, this::method2);
temp.put(HwErrorsEtlConstants.MR_RAW_RFAMP_ERRORS, this::method3);
MAPPING = Collections.unmodifiableMap(temp);
}
Luego, en su método que puede utilizar Stream
s introdujo también en Java 8:
// Optional indicates a potentially absent value, it's just a wrapper around a Runnable
Optional<Runnable> optional = MAPPING
// create a Stream from the entries
.entrySet().stream()
// keep the items that match the condition and drop every other
.filter(e -> filename.startsWith(e.getKey()))
// we had Map.Entry<String, Runnable>, but now we only need the value e.g. the Runnable
.map(Map.Entry::getValue)
// short circuit, e.g. we only want the first value that matches
.findFirst();
// checks if anything is present, this is used as the MAPPING "could" be empty
if(optional.isPresent()) {
// unpack the value and call it with arguments
optional.get().run(aWriter, someFileName, anInputStream);
} else {
// nothing matched, throw error or log etc.
}
Aunque como se ha mencionado, la solución actual tiene un aspecto muy bien, supongo que está utilizando Sonar para análisis de código. A veces simplemente Sonar tiene falsos positivos, por lo que también se puede ignorar de forma segura.
Además lee para ayudarle a entender Java 8: