[JAVA] The guy who can't handle errors in the stream

The one who gets angry when you catch the exception

I can't write in one line ...

It's a guy who manages to write beautifully

Preparation

Preparation.java


	/** --------------------Preparation-------------------- */
	/**Interface that throws an exception*/
	private static interface Throwable<T, S> {
		S apply(T t) throws NullPointerException, NumberFormatException, Exception;
	}
	/**Method to switch the function to be executed according to the exception*/
	private static <T, S> Function<T, S> switchFunction(Throwable<T, S> tf, BiFunction<Exception, T, S> npe,
			BiFunction<Exception, T, S> nfe, Function<Exception, S> other) {
		return v -> {
			try {
				return tf.apply(v);
			} catch (NullPointerException e) {
				return npe.apply(e, v);
			} catch (NumberFormatException e) {
				return nfe.apply(e, v);
			} catch (Exception e) {
				return other.apply(e);
			}
		};
	}

I made a Function that can throw an exception If you get an exception when you try to execute a certain Function, make this Function.

I will implement the four

Implementation of internal processing

internal.java


	/** --------------------Implementation of specific processing-------------------- */
	/**Main processing*/
	private static final Throwable<String, Integer> tf = v -> {
		if (v.equals("5")) {
			return Integer.parseInt(v);
		} else if (v.equals("999")) {
			throw new NullPointerException();
		} else if (v.equals("ddd")){
			throw new NumberFormatException();
		} else {
			throw new IOException();
		}
	};
	/**Processing at the time of Nullpo*/
	private static final BiFunction<Exception, String, Integer> npe = (e, v) -> {
		e.printStackTrace();
		return 0;
	};
	/**Processing when numerical conversion is not possible*/
	private static final BiFunction<Exception, String, Integer> nfe = (e, v) -> {
		e.printStackTrace();
		return v.length();
	};
	/**Handling of other exceptions*/
	private static final Function<Exception, Integer> other = e -> {
		e.printStackTrace();
		return 1;
	};

This time it seems to be all patterns, so I forced to throw an Exception Let's do it

Run

Run.java


	/** --------------------Run-------------------- */
	public static void main(String[] args) {
		Arrays.asList("5", "ddd", "999", "0").stream().map(switchFunction(tf, npe, nfe, other))
				.forEach(System.out::println);
	}
5
java.lang.NumberFormatException
	at test1.Test1.lambda$0(Test1.java:35)
	at test1.Test1.lambda$4(Test1.java:18)
	at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
	at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at test1.Test1.main(Test1.java:55)
3
java.lang.NullPointerException
	at test1.Test1.lambda$0(Test1.java:33)
	at test1.Test1.lambda$4(Test1.java:18)
	at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
	at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at test1.Test1.main(Test1.java:55)
0
java.io.IOException
	at test1.Test1.lambda$0(Test1.java:37)
	at test1.Test1.lambda$4(Test1.java:18)
	at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
	at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at test1.Test1.main(Test1.java:55)
1

As expected

Weaknesses

Well, as you can see, the types of Function arguments and return values that can be implemented are Even though I'm taking it with generics, it's useless if they don't all match.

It seems that there will be cases where it will be a problem if it is a realistic implementation. I mean, it seems that if you stack Functions like this, it will be heavy ...

Because the execution part and the internal processing are neatly separated I think the readability is very high. But yeah, the preparation is too long

If there are multiple cases where an Exception is inevitably thrown in an intermediate operation for a series of streams It seems that it is better to implement this kind of implementation.

Try this with a method

This is it.java


public class Test7 {
	private static <T>void switchMethod(T t) {
		try {
			s1(t);
		} catch (NumberFormatException e) {
			s2(t);
		}
	}
	private static <T>void s1(T t) throws NumberFormatException{
		System.out.println(Integer.parseInt((String) t));
	}
	private static <T>void s2(T t) {
		System.out.println(t + "Suchimuri");
	}
	public static void main(String[] args) {
		List<String> list = new ArrayList<>(Arrays.asList("a", null, "2"));
		list.stream().forEachOrdered(Test7::switchMethod);
	}
}
a Suuchimuri
null
2

After all, the number of methods will increase in the preparation stage.

If the behavior when throwing an exception is the same, it is better to use it, but ...

Hmmm, difficult ...

Recommended Posts

The guy who can't handle errors in the stream
The guy who tries-with-resources with kotlin
Try using the Stream API in Java
The guy who replicates sessions with tomcat
To you who were told "Don't use Stream API" in the field