Javapoet: writing the same thing with less line of code (addModifiers) - java

So, I have this code (using the Javapoet Lib):
if (myBeautifulBoolean) <--------------------------
theClass = TypeSpec.classBuilder(classe.getName())
.addModifiers(javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase()), Modifier.FINAL) <-------------------
.superclass(father==null?ClassName.OBJECT:father)
.addMethods(methods)
.addFields(fields)
.build();
else
theClass = TypeSpec.classBuilder(classe.getName())
.addModifiers(javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase())) <------------------
.superclass(father==null?ClassName.OBJECT:father)
.addMethods(methods)
.addFields(fields)
.build();
and i want it to become something like:
theClass = TypeSpec.classBuilder(classe.getName())
.addModifiers(javax.lang.model.element.Modifier.valueOf(classe.getProte().toString().toUpperCase()), myBeautifulBoolean?Modifier.FINAL:null) <----------
.superclass(father==null?ClassName.OBJECT:father)
.addMethods(methods)
.addFields(fields)
.build();
Where is the problem?
if i write myBeautifulBoolean?Modifier.FINAL:null, I get an exception because the parameters of addmodifiers() cannot be null, and there is nothing like Modifier.NOTFINAL
So, is there a way to tell the code "Ehi, if the boolean is true, add an argument, if not, don't"?

addModifiers takes an array. you could do addModifiers(test ? new Modifier[] { mod, Modifier.FINAL} : new Modifier[] { mod }) you could make this prettier with a helper method
public static <T> T[] arr(T... array) { return array; }
// later
.addModifiers(test ? arr(mod, FINAL) : arr(mod))

Related

Possibility of getOrElseReturn in Kotlin

I often have a problem with Optional and similar classes Option, Try, Either from VAVR for example.
Let's say I have some Optional, and if it's empty I want to immediately return from a method (without exception, since my method is returning Optional aswell, so getOrElseThrow is out of the picture) and if it's present I want to further process it.
public Optional<Integer> converter() {
Optional<String> opt = getSomething();
if(!opt.isPresent())
return Optional.empty();
String value = opt.get();
// some manipulations on value, such as map and flatMap would cause a huge mess
return Integer.parseInt(value);
}
I just need to return immediately in case value is empty, I can't do chain of map and flatMap. The whole pain is doing .get(). Something like getOrElseThrow, but with return instead of throw would be fantastic - getOrElseReturn. Obviously not possible in Java, so I thought about trying this in Kotlin.
fun safeOptional(): Optional<Int> {
val extracted = Optional.of("123")
.getOrElseReturn { return Optional.empty() }
val modified = extracted.toInt() * 2
return Optional.of(modified)
}
private inline fun <T> Optional<T>.getOrElseReturn(block: (Optional<T>) -> T): T {
return if (!this.isPresent)
block(this)
else
this.get()
}
Much to my surprise it actually does what I want. If I change the Optional.of("123") to Optional.empty() it immediately returns from a method. I don't understand how it compiles though.
My method needs a block: (Optional<T>) -> T, otherwise it wouldn't compile. So in my case I have Optional<String> and I need to pass a block: (Optional<String>) -> String, but hey - the block that I have is nowhere close to this and it still compiles, how?
When I extract the block to variable it becomes val block: (Optional<String>) -> Nothing (I guess return statement is Nothing) and it still compiles, surprising me even more.
btw I know this code is not strictly what I want - someone can pass another block without non-local return to the method, but I don't think there is another way
Extract the second part of your method into another private method and call getSomething().map(this::otherPrivateMethod)
It will not be invoked if no value is present in getSomething()
Basically,
public Optional<Integer> converter() {
return getSomething().map(this::privateConverter);
}
private Integer privateConverter(Integer integer) {
// some manipulations on value, such as map and flatMap would cause a huge mess
return Integer.parseInt(value);
}
Answering the Kotlin part:
fun safeOptional(): Optional<Int> {
val extracted = Optional.of("123")
.getOrElseReturn { return Optional.empty() }
.......
}
The return here is not return from a lambda, but rather a return from function safeOptional so therefore lambda doesn't return anything (it returns Nothing). Lambda returning Nothing can be passed as lambda returning anything.
To get a compile error, you should return from lambda instead:
val extracted = Optional.of("123")
.getOrElseReturn { return#getOrElseReturn Optional.empty() }
Generally, Optional are not needed in Kotlin. You should use nullable types instead. You would combine them with nullsafe operators (e.g. the Elvis operator -- ?::
fun nullsafe(x: String?): Optional<Int> {
val extracted = x ?: return Optional.empty()
val modified = extracted.toInt() * 2
return Optional.of(modified)
}
nullsafe("2") // => Optional[4]
nullsafe(null) // => Optional.empty

How to flip an Option<Try<Foo>> to a Try<Option<Foo>>

I have an Try<Option<Foo>>. I want to flatMap Foo into a Bar, using it using an operation that can fail. It's not a failure if my Option<Foo> is an Option.none(), (and the Try was a success) and in this case there's nothing to do.
So I have code like this, which does work:
Try<Option<Bar>> myFlatMappingFunc(Option<Foo> fooOpt) {
return fooOpt.map(foo -> mappingFunc(foo).map(Option::of) /* ew */)
.getOrElse(Try.success(Option.none()); // double ew
}
Try<Bar> mappingFunc(Foo foo) throws IOException {
// do some mapping schtuff
// Note that I can never return null, and a failure here is a legitimate problem.
// FWIW it's Jackson's readValue(String, Class<?>)
}
I then call it like:
fooOptionTry.flatMap(this::myFlatMappingFunc);
This does work, but it looks really ugly.
Is there a better way to flip the Try and Option around?
Note 1: I actively do not want to call Option.get() and catch that within the Try as it's not semantically correct. I suppose I could recover the NoSuchElementException but that seems even worse, code-wise.
Note 2 (to explain the title): Naively, the obvious thing to do is:
Option<Try<Bar>> myFlatMappingFunc(Option<Foo> fooOpt) {
return fooOpt.map(foo -> mappingFunc(foo));
}
except this has the wrong signature and doesn't let me map with the previous operation that could have failed and also returned a successful lack of value.
When you are working with monads, each monad type combine only with monads of same type. This is usually a problem because the code will come very unreadable.
In the Scala world, there are some solutions, like the OptionT or EitherT transformers, but do this kind of abstractions in Java could be difficult.
The simple solution is to use only one monad type.
For this case, I can think in two alternatives:
transform fooOpt to Try<Foo> using .toTry()
transform both to Either using .toEither()
Functional programmers are usually more comfortable with Either because exceptions will have weird behaviors, instead Either usually not, and both works when you just want to know why and where something failed.
Your example using Either will look like this:
Either<String, Bar> myFlatMappingFunc(Option<Foo> fooOpt) {
Either<String, Foo> fooE = fooOpt.toEither("Foo not found.");
return fooE.flatMap(foo -> mappingFunc(foo));
}
// Look mom!, not "throws IOException" or any unexpected thing!
Either<String, Bar> mappingFunc(Foo foo) {
return Try.of(() -> /*do something dangerous with Foo and return Bar*/)
.toEither().mapLeft(Throwable::getLocalizedMessage);
}
I believe this is simply a sequence function (https://static.javadoc.io/io.vavr/vavr/0.9.2/io/vavr/control/Try.html#sequence-java.lang.Iterable-) that you are looking for:
Try.sequence(optionalTry)
You can combine Try.sequence and headOption functions and create a new transform function with a little better look, in my opinion, also you can use generic types to get a more reusable function :) :
private static <T> Try<Option<T>> transform(Option<Try<T>> optT) {
return Try.sequence(optT.toArray()).map(Traversable::headOption);
}
If I understand correctly, you want to :
keep the first failure if happens
swap the second when mapping to json for an empty option.
Isn t it simpler if you decompose your function in such a way:
public void keepOriginalFailureAndSwapSecondOneToEmpty() {
Try<Option<Foo>> tryOptFoo = null;
Try<Option<Bar>> tryOptBar = tryOptFoo
.flatMap(optFoo ->
tryOptionBar(optFoo)
);
}
private Try<Option<Bar>> tryOptionBar(Option<Foo> optFoo) {
return Try.of(() -> optFoo
.map(foo -> toBar(foo)))
.orElse(success(none())
);
}
Bar toBar(Foo foo) throws RuntimeException {
return null;
}
static class Bar {
}
static class Foo {
}
The solution of throughnothing and durron597 helped me there. This is my groovy test case:
def "checkSomeTry"() {
given:
def ex = new RuntimeException("failure")
Option<Try<String>> test1 = Option.none()
Option<Try<String>> test2 = Option.some(Try.success("success"))
Option<Try<String>> test3 = Option.some(Try.failure(ex))
when:
def actual1 = Try.sequence(test1).map({ t -> t.toOption() })
def actual2 = Try.sequence(test2).map({ t -> t.toOption() })
def actual3 = Try.sequence(test3).map({ t -> t.toOption() })
then:
actual1 == Try.success(Option.none())
actual2 == Try.success(Option.some("success"))
actual3 == Try.failure(ex)
}

how to port java inner function in Scala?

How can I port a java inner function from here
which fully is contained in to Scala?
JavaPairRDD<Envelope, HashSet<Point>> castedResult = joinListResultAfterAggregation.mapValues(new Function<HashSet<Geometry>,HashSet<Point>>()
{
#Override
public HashSet<Point> call(HashSet<Geometry> spatialObjects) throws Exception {
HashSet<Point> castedSpatialObjects = new HashSet<Point>();
Iterator spatialObjectIterator = spatialObjects.iterator();
while(spatialObjectIterator.hasNext())
{
castedSpatialObjects.add((Point)spatialObjectIterator.next());
}
return castedSpatialObjects;
}
});
return castedResult;
My approach as outlined below would not compile due to some NotinferredU
val castedResult = joinListResultAfterAggregation.mapValues(new Function[java.util.HashSet[Geometry], java.util.HashSet[Point]]() {
def call(spatialObjects: java.util.HashSet[Geometry]): java.util.HashSet[Point] = {
val castedSpatialObjects = new java.util.HashSet[Point]
val spatialObjectIterator = spatialObjects.iterator
while (spatialObjectIterator.hasNext) castedSpatialObjects.add(spatialObjectIterator.next.asInstanceOf[Point])
castedSpatialObjects
}
})
When asking a question about compilation errors please provide the exact error, especially when your code doesn't stand on its own.
The inner function itself is fine; my guess would be that due to changes above joinListResultAfterAggregation isn't a JavaPairRDD anymore, but a normal RDD[(Envelope, Something)] (where Something could be java.util.HashSet, scala.collection.Set or some subtype), so its mapValues takes a Scala function, not a org.apache.spark.api.java.function.Function. Scala functions are written as lambdas: spatialObjects: Something => ... (the body will depend on what Something actually is, and the argument type can be omitted in some circumstances).
How about this ?
val castedResult = joinListResultAfterAggregation.mapValues(spatialObjects => {
spatialObjects.map(obj => (Point) obj)
})

JMockit | trying to define different return values based on parameters but getting unexpected results

I've got a class like the following:
class A
{
public method doSomething()
{
//....
DAO dataAccessor = new DAO();
List<Object> result1 = dataAccessor.getData(dataAccessor.getSql1());
List<Object> result2 = dataAccessor.getData(dataAccessor.getSql2());
//.. do some stuff with the results
}
Now, I use jMockit for testing the above function, by mocking the DAO class.
This is how my test class looks like:
class A_Test
{
private A myAClass;
#Mocked DAO mockedDAO;
List<Object> resultToSql1, resultToSql2;
// ... Some initializations...
#Test
public void testDoSomething()
{
new NonStrictExpectations()
{
mockedDAO.getSql1(); result = "SQL1";
mockedDAO.getData(withEqual("SQL1")); result = resultToSql1;
mockedDAO.getSql2(); result = "SQL2";
mockedDAO.getData(withEqual("SQL2")); result = resultToSql2;
};
myAClass.doSomething();
}
}
Now, it seems that the second expectation regarding getData() masks the first one, i.e. the mock object behaves as if I never declared the first lines in the expectation (the ones that handle sql1):
The first call to getData() returns empty collection, instead of the values with which I initialized resultToSql1. The second call returns resultToSql2, as expected.
If I comment the following line:
mockedDAO.getData(withEqual("SQL2")); result = resultToSql2;
the first call is returning what I defined - resultToSql1, and the second returns empty collection.
This makes sense.
So, what am I doing wrong? ?How can I define two different return values from getData() based on the parameters of the call?
Any help would be appreciated.
Thanks!
So, After digging more deeply inside the manual, I found that:
...But what if a test needs to decide the result of a recorded invocation based on the arguments it will receive at replay time? We can do it through a mockit.Delegate instance ...
So, in order to solve the above problem, the expectations block should look like this:
new NonStrictExpectations()
{
mockedDAO.getSql1(); result = "SQL1";
mockedDAO.getSql2(); result = "SQL2";
mockedDAO.getData(anyString);
result = new mockit.Delegate()
{
List<Object> getData(String sql)
{
if (sql.equals("SQL1"))
return resultToSql1;
if (sql.equals("SQL2"))
return resultToSql2;
return null;
}
}
};

Google Collections Suppliers and Find

I'm looking for a Google Collections method that returns the first result of a sequence of Suppliers that doesn't return null.
I was looking at using Iterables.find() but in my Predicate I would have to call my supplier to compare the result against null, and then have to call it again once the find method returned the supplier.
Given your comment to Calm Storm's answer (the desire not to call Supplier.get() twice), then what about:
private static final Function<Supplier<X>, X> SUPPLY = new Function<....>() {
public X apply(Supplier<X> in) {
// If you will never have a null Supplier, you can skip the test;
// otherwise, null Supplier will be treated same as one that returns null
// from get(), i.e. skipped
return (in == null) ? null : in.get();
}
}
then
Iterable<Supplier<X>> suppliers = ... wherever this comes from ...
Iterable<X> supplied = Iterables.transform(suppliers, SUPPLY);
X first = Iterables.find(supplied, Predicates.notNull());
note that the Iterable that comes out of Iterables.transform() is lazily-evaluated, therefore as Iterables.find() loops over it, you only evaluate as far as the first non-null-returning one, and that only once.
You asked for how to do this using Google Collections, but here's how you would do it without using Google Collections. Compare it to Cowan's answer (which is a good answer) -- which is easier to understand?
private static Thing findThing(List<Supplier<Thing>> thingSuppliers) {
for (Supplier<Thing> supplier : thingSuppliers) {
Thing thing = supplier.get();
if (thing != null) {
return thing;
}
}
// throw exception or return null
}
In place of the comment -- if this was the fault of the caller of your class, throw IllegalArgumentException or IllegalStateException as appropriate; if this shouldn't have ever happened, use AssertionError; if it's a normal occurrence your code that invokes this expects to have to check for, you might return null.
What is wrong with this?
List<Supplier> supplierList = //somehow get the list
Supplier s = Iterables.find(supplierList, new Predicate<Supplier>(){
boolean apply(Supplier supplier) {
return supplier.isSomeMethodCall() == null;
}
boolean equals(Object o) {
return false;
}
});
Are you trying to save some lines? The only optimisation I can think is to static import the find so you can get rid of "Iterables". Also the predicate is an anonymous inner class, if you need it in more than one place you can create a class and it would look as,
List<Supplier> supplierList = //somehow get the list
Supplier s = find(supplierList, new SupplierPredicateFinder());
Where SupplierPredicateFinder is another class.
UPDATE : In that case find is the wrong method. You actually need a custom function like this which can return two values. If you are using commons-collections then you can use a DefaultMapEntry or you can simply return an Object[2] or a Map.Entry.
public static DefaultMapEntry getSupplier(List<Supplier> list) {
for(Supplier s : list) {
Object heavyObject = s.invokeCostlyMethod();
if(heavyObject != null) {
return new DefaultMapEntry(s, heavyObject);
}
}
}
Replace the DefaultMapEntry with a List of size 2 or a hashmap of size 1 or an array of length 2 :)

Categories

Resources