I have defined this stream:
public int sumNumbers(int[] numbers) {
return IntStream.of(numbers)
.filter(n -> n <= 1000)
.sum();
}
Where I'm summing all integers that are not higher than 1000. But now what I want to do is, throw an exception if any element of the array is negative.
I know how to do it in the old fashioned mode, but I was wondering if there's any mechanism with Stream and .filter() where I can define a filter and an exception case for that filter
Just to clarify I want to throw an exception, and not control a runtime exception as the other question does.
The idea here is that if my filter is true in:
filter(n -> n < 0 throw Exception)
There's an IllegalArgumentException in JDK which is unchecked and informs about wrong function input, so it can be used here:
IntStream.of(numbers)
.peek(n -> {
if (n < 0) throw new IllegalArgumentException(String.valueOf(n));
})
.sum();
In general, currently Java develops towards unchecked-only exceptions. There's even UncheckedIOException class added in Java-8!
Related
This question already has answers here:
How do you assert that a certain exception is thrown in JUnit tests?
(35 answers)
JUnit 5: How to assert an exception is thrown?
(12 answers)
Closed 3 months ago.
I'm trying to test if an exception with a customized message is thrown when a division by zero is attempted.
Here's the method:
public static int getMultiplesOfGivenNumber(int number, int[] array){
int multiples = 0;
if (number == 0) {
throw new ArithmeticException("Number cannot be zero");
}else{
for (int i = 0; i < array.length; i++) {
if (array[i] % number == 0) {
multiples += 1;
}
}
}
After searching some solutions, I found this as a way to do the thing, but my IDE can't recognize 'expected' ...
#Test(expected=java.lang.ArithmeticException.class)
public void testDivideByZero(){
//arrange
int number = 0;
//act
int result = B3_E2.getMultiplesOfGivenNumber(number, intervalFromOneToTen());
//assert
assertEquals(expected, result);
}
I'm just unaware why my IDE is not recognizing 'expected'. Don't know if this has something to do with Junit version, or if there's some issue with the syntax I'm using.
In every other tests I used so far I never put nothing after #Test. I just found out this solution in another thread for a similar problem.
The expected argument to the #Test annotation exists only since JUnit 4. You must be using an earlier version of JUnit.
That having been said, you do not have to use this annotation, so you do not have to upgrade to JUnit 4 just for this feature.
You can use a try...catch yourself, and assert that the exception was thrown, and also assert that the custom message is what it is supposed to be.
#Test
public void testDivideByZero()
{
try
{
B3_E2.getMultiplesOfGivenNumber( 0, intervalFromOneToTen() );
assertTrue( false ); //expected exception was not thrown
}
catch( ArithmeticException e )
{
assertEquals( e.getMessage(), "Number cannot be zero" );
}
}
The benefit of going this way is that you can get your hands on the exception object, so you can examine its contents and make sure that it was initialized as expected. In the case of ArithmeticException there is nothing to check other than the message, but in other cases there may be a lot more to check.
Assuming you have an exception (checked/unchecked) in a stream operation
and you want to ignore from now on this element.
The stream must not be aborted, just ignoring elements throwing exceptions.
I explicitly avoid saying skip, because it is a stream operation.
So the example is using the map() operation for demonstration.
Here I have a division by zero (for example), so the "map" should skip this
element.
As an example:
#Test
public void ignoreException() {
assertThat(Stream.of(1,2,1,3).map(i -> 10 / i).reduce(0, Integer::sum), is(28));
// the zero will break the next stream
assertThat(Stream.of(1,2,0,3).map(i -> 10 / i).reduce(0, Integer::sum), is(18));
}
So the division by zero can break the whole stream.
I found a lot of articles that wrap a runtime exception in a checked exception (throw new RuntimeException(ex)).
Or partial vs. total functions.
Or I made a wrapper returning a java.util.function.Function
(e.g: ....map(wrapper(i -> 10/i))...),
returning a "null" in the case of a exception. But right-hand operation may now fail,
as in my example (reduce).
The only useful approach is an "EITHER" concept (a stream of EITHER),
so the division by zero in my example
will become a "left" and can be handled in a different way.
There are relatively few operations on streams that can achieve a transformation of elements and result in elements being dropped -- in fact, there's really only one, flatMap.
So your wrapper more or less has to look like
interface CanThrow<F, T> { T apply(F from) throws Exception; }
<T, R> Function<T, Stream<R>> wrapper(CanThrow<T, R> fn) {
return t -> {
try {
return Stream.of(fn.apply(t));
} catch (Exception ignored) { return Stream.empty(); }
}
}
assertThat(Stream.of(1, 2, 0, 3).flatMap(wrapper(i -> 10 / i)).reduce(0, Integer::sum))
.isEqualTo(18));
Try this:
#Test
public void ignoreException() {
assertThat(Stream.of(1,2,1,3).map(i -> i == 0 ? 0 : 10 / i).reduce(0, Integer::sum), is(28));
// the zero will break the next stream
assertThat(Stream.of(1,2,0,3).map(i -> i == 0 ? 0 : 10 / i).reduce(0, Integer::sum), is(18));
}
This question already has answers here:
How can I throw CHECKED exceptions from inside Java 8 lambdas/streams?
(18 answers)
Closed 4 years ago.
I have a method with nested for loops as follows:
public MinSpecSetFamily getMinDomSpecSets() throws InterruptedException {
MinSpecSetFamily result = new MinSpecSetFamily();
ResourceType minRT = this.getFirstEssentialResourceType();
if (minRT == null || minRT.noSpecies()) {
System.out.println("There is something wrong with the "
+ "minimal rticator, such as adjacent to no species. ");
}
for (Species spec : minRT.specList) {
ArrayList<SpecTreeNode> leafList = this.getMinimalConstSpecTreeRootedAt(spec).getLeaves();
for (SpecTreeNode leaf : leafList) {
result.addSpecSet(new SpecSet(leaf.getAncestors()));
}
}
return result;
}
This works fine, but the application is performance critical so I modified the method to use parallelStream() as follows:
public MinSpecSetFamily getMinDomSpecSets() throws InterruptedException {
ResourceType minRT = this.getFirstEssentialResourceType();
if (minRT == null || minRT.noSpecies()) {
System.out.println("There is something wrong with the "
+ "minimal rticator, such as adjacent to no species. ");
}
MinSpecSetFamily result = minRT.specList.parallelStream()
.flatMap(spec -> getMinimalConstSpecTreeRootedAt(spec).getLeaves().parallelStream())
.map(leaf -> new SpecSet(leaf.getAncestors()))
.collect(MinSpecSetFamily::new, MinSpecSetFamily::addSpecSet, MinSpecSetFamily::addMSSF);
return result;
}
This worked fine until I wanted to introduce an InterruptedException in the 'getLeaves()' method. Now the parallelStream version will not compile as it says I have an unreported InterruptedException which must be caught or declared to be thrown. I think this is because the parallelStream runs on multiple threads. No combination of try/catch blocks suggested by my IDE resolves the issue.
The second solution posted in Interrupt parallel Stream execution
suggests that I may be able to resolve the issue using ForkJoinPool but I have been unable to figure out how to modify my method to use this approach.
If you want to stick to your current design, you just need to catch the exception:
.flatMap(spec -> {
try {
return getMinimalConstSpecTreeRootedAt(spec).getLeaves().parallelStream();
} catch (InterruptedException e) {
// return something else to indicate interruption
// maybe an empty stream?
}
}).map(...)
Note that a parallel stream of parallel streams is possibly unnecessary and parallelising the top level stream only may be sufficient performance-wise.
The doc says
Conceptually, it is a union of Single and Completable providing the
means to capture an emission pattern where there could be 0 or 1 item
or an error signalled by some reactive source.
But I am not sure what it truly means. It seems it is java8's Optional.
The following two codes have the same result , but I don't know what Maybe can do and Optional cannot (or cumbersome) do.
#Test
public void testMaybe1() {
Observable.just(3, 2, 1, 0, -1)
.map(i -> {
try {
int result = 6 / i;
return Maybe.just(result);
} catch (Exception e) {
return Maybe.empty();
}
})
.blockingForEach(maybe -> {
logger.info("result = {}", maybe.blockingGet());
}
);
}
#Test
public void testMaybe2() {
Observable.just(3, 2, 1, 0, -1)
.map(i -> {
try {
int result = 6 / i;
return Optional.of(result);
} catch (Exception e) {
return Optional.empty();
}
})
.blockingForEach(opt -> {
logger.info("result = {}", opt.orElse(null));
}
);
}
The results are the same :
result = 2
result = 3
result = 6
result = null
result = -6
In rxJava1 , My API used to return Observable<Optional<T>> , Is it a bad smell ? Should I change to Observable<Maybe<T>> ?
Maybe is a wrapper around an operation/event that may have either
A single result
No result
Error result
However Optional is a wrapper around a value that may either be
Present
Absent
In your example, in the map operation, the computation is synchronous (i.e. 6/i is synchronous and can result in a value immediately) and you want to propagate a value (if division is possible) or empty value (if division is not possible). Hence using Optional makes more sense.
There are however other options also:
If you want to propagate why division is not possible then you would want to report the exception that occurred. In such a case using Maybe will make more sense.
If you are not interested in both empty value and reason of error, then you simply want to skip propagating those results. In such a scenario I would use a flatMap instead of map. I will then not have to use any of Optional or Maybe.
.flatMap(i -> {
try {
int result = 6 / i;
return Observable.just(result);
} catch (Exception e) {
return Observable.empty();
}
})
Maybe is also useful when you have an Observable that can emit multiple values but you are interested in, let's say, only the first one and hence you use the firstElement() operator on the Observable. This returns a Maybe because either there is a single value, or there is no value (if source Observable does not emit any value before completing) or there is an error (if source Observable errors before emitting any value).
Maybe is a lazy stream of zero or one things (and being a stream can result in an error). Optional is not lazy, it it is either present or absent. There is no sense of deferred calculation with an Optional whereas there is with Maybe.
The difference relevant to your question is that Maybe can propagate error while Optional cannot - in your example one cannot distinguish between error and empty result. If error handling is important, Optional is useless, while Maybe has Maybe.error(Throwable). API-wise, for your use case I would prefer Single to Maybe - because it yields either Error or single Result, so return type would be Observable<Single<T>>
RxJava 2 targets Java 6. This means there is no builtin Optional support guaranteed, and they have to bring their own. Similar to how they have to bring their own Function types.
If your application/library only supports Java >= 8 you can use whatever suits you better.
I have 2 classes, one that implements a double lookup( int i);
and one where I use that lookup(int i) in solving a question, or in this case printing the lookup values. This case is for an array.
So I read the exception documentation or google/textbook and come with the following code:
public double lookup(int i) throws Exception
{
if( i > numItems)
throw new Exception("out of bounds");
return items[i];
}
and take it over to my class and try to print my set, where set is a name of the
object type I define in the class above.
public void print()
{
for (int i = 0; i < set.size() - 1; i++)
{
System.out.print(set.lookup(i) + ",");
}
System.out.print(set.lookup(set.size()));
}
I'm using two print()'s to avoid the last "," in the print, but am getting an
unhandled exception Exception (my exception's name was Exception)
I think I have to catch my exception in my print() but cannot find the correct formatting online. Do I have to write
catch exception Exception? because that gives me a syntax error saying invalid type on catch.
Sources like
http://docs.oracle.com/javase/tutorial/essential/exceptions/
are of little help to me, I'm can't seem to grasp what the text is telling me. I'm also having trouble finding sources with multiple examples where I can actually understand the coding in the examples.
so could anybody give me a source/example for the above catch phrase and perhaps a decent source of examples for new Java programmers? my book is horrendous and I cannot seem to find an understandable example for the above catch phrase online.
I wouldn't throw Exception ever.
In your case, IndexOutOfBoundException or InvalidArgumentException would eb a better choice. As these are not checked Exceptions, you don't need to catch them.
public double lookup(int i) {
if(i >= numItems) // assuming numItems is not items.length
throw new IndexOutOfBoundException("out of bounds " + i + " >= " + numItems);
return items[i];
}
Note: the check should be >=
Your print() method will now compile unchanged.
What is Exception?
Exceptions are for exceptional conditions. Conditions that normally do not occur. Take an example you went to withdraw money and your account has 100 balance and you asked for 200 then ATM should tell you that you have insufficient balance.
Types of Exceptions
Checked Exception
These are conditions where application wants to recover from it. Like example given above application will give you error and will continue working.
Error
This is an exceptional condition which is external to application. We say OutOfMemoryError when there isn't enough memory available and application can not recover from it.
Runtime Exception /Unchecked Exception
These exceptions are applications exception but in this case application can not recover from it. E.g NullpointerException if value is null and you try do something nasty with it.
so of above three only checked exceptions need to be cached.
How to throw and Catch Checked Exception
Exception or any subclass of Exception is a checked exception. A checked exception can be thrown using throw clause. Once you throw an exception it becomes mandatory for you to include that in method declaration using throws clause.
So whoever want to use this method will now have to handle that exception. Handling exception means invoking alternative flows. Like in our case we displayed text to user "Error Invalid account number."
Calling function can also choose to propagate exceptions by adding throws clause for those exceptions which are thrown by method it is calling.
Generate:
public static double withdraw(int i) throws Exception {
if (i <= 0)// Out of bounds
throw new Exception("Invalid Account Number");
return 0.0;// something;
}
Handle:
try {
withdraw(0);
} catch (Exception e) {
// do something with exception here.
// Log the exception
System.out.println("Error Invalid account number.");
}
Propagate:
public static double callWithdraw(int i) throws Exception {//Propagate exceptions
return withdraw(i);
}
Try this
try
{
print(); //print() needs to throw the same exception
} catch(Exception e)
{
//handle exception
System.err.println(e.getMessage()+"\n\n"+e.printStackTrace());
}
//finally {
// cleanup here if you like
// }
or this
public void print()
{
for (int i = 0; i < set.size() - 1; i++)
{
try
{
System.out.print(set.lookup(i) + ",");
} catch(Exception e)
{
//handle it here
}
}
System.out.print(set.lookup(set.size()));
}
Do note that using "throws" is kind of a easy way out; it's a cheap delegation that sometimes makes coding easier... if you can, you should try to always use try/catch instead of throws.
Just be aware that whenever you use something with "throws" eventually you will have to put that in a try/catch block and deal with it properly.
Generally to denote improper arguments passed into your method, use IllegalArgumentException which is a RuntimeException and should not be caught.
In this specific case you don't have to write any extra code, the ArrayIndexOutOfBoundsException should take care of improper array access.
Thrown to indicate that an array has been accessed with an illegal
index. The index is either negative or greater than or equal to the
size of the array.