I have a list that has to accept either a list of Integer/Double/Float/Long and return the sum.
I tried this
public static Number getSum(List< ? extends Number> lst) {
return lst.stream().reduce(0.0, (a, b) -> a+b);
}
But I am getting this error in compile time
The operator + is undefined for the argument type(s) capture#3-of ? extends java.lang.Number, capture#3-of ? extends java.lang.Number
There can be a custom subclass of Number, that cannot be applied to +.
E.g. you declared a class Natural
class Natural extends Number {
...
}
You can't add it using plus operator.
So I think the best you can to is to cast them to double first.
public static Number getSum(List< ? extends Number> lst) {
return lst.stream().mapToDouble(Number::doubleValue).sum();
}
Related
Background
I'm developing a Spring Boot application and I'm using Kotlin, IntelliJ and Gradle (Groovy). I have some enum class in my code and I need to persist them (with JPA). I used a simple global converter.
// Sample Enum
enum class Policy {
PUBLIC,
INVITE_ONLY
}
// Sample Converter
#Converter(autoApply = true)
class PolicyConverter : AttributeConverter<Policy, String> {
override fun convertToDatabaseColumn(attribute: Policy): String {
return attribute.name
}
override fun convertToEntityAttribute(dbData: String): Policy {
return Policy.valueOf(dbData.toUpperCase())
}
}
Problem
Since I have 5-6 enums and I hate duplicated code, I thought about a generic converter that should do the work for every given enum. I tried to code something, but nothing worked. This is what I was thinking about:
abstract class EnumConverter<E: Enum<E>> : AttributeConverter<E, String> {
override fun convertToDatabaseColumn(attribute: E): String {
return attribute.name
}
override fun convertToEntityAttribute(dbData: String): E {
return E.valueOf(dbData.toUpperCase())
}
}
In this way I can only extend from one abstract class every enum converter, like so:
#Converter(autoApply = true)
class PolicyConverter : EnumConverter<Policy>() {}
Problem with this code is that I have two errors:
E is red because: Type parameter 'E' cannot have or inherit a companion object, so it cannot be on the left hand side of dot
valueOf is red because: unresolved reference (there are like 150+ types of .valueOf).
As suggested from this I tried to use following function:
private inline fun <reified E : Enum<E>> getValue(string: String): E {
return enumValueOf(string.toUpperCase())
}
But when called from the .convertToEntityAttribute, the result is that "Cannot use 'E' as reified type parameter. Use a class instead."
Question
So the question is simple: how can I implement an easy and fast way to make one converter for all my enums, that all follows the same principle? I just need a return E.valueOf(<value>) function, but it's not present.
A simply workaround of this problem is to define an abstract method that every class will implement and it will return the correct type, given a string.
// Inside EnumConverter, the Generic Class
abstract class EnumConverter<E: Enum<E>> : AttributeConverter<E, String> {
abstract fun getValueFromString(string: String) : E
override fun convertToEntityAttribute(dbData: String): E {
return getValueFromString(dbData)
}
[...]
}
// Inside Policy Enum, implementing
class PolicyConverter : EnumConverter<Policy>() {
override fun getValueFromString(string: String): Policy {
return Policy.valueOf(string.toUpperCase())
}
}
But it's a workaround that I really dislike.
I am trying to perform reactive repository test however even compiler do not throw any error in code editor code won't compile. Why is that?
Error:(52, 21) java: no suitable method found for create(com.geborskimateusz.microservices.core.recommendation.persistence.RecommendationEntity)
method reactor.test.StepVerifier.<T>create(org.reactivestreams.Publisher<? extends T>) is not applicable(inferred type does not conform to upper bound(s) inferred: com.geborskimateusz.microservices.core.recommendation.persistence.RecommendationEntity
upper bound(s): org.reactivestreams.Publisher<? extends java.lang.Object>,com.geborskimateusz.microservices.core.recommendation.persistence.RecommendationEntity)method reactor.test.StepVerifier.<T>create(org.reactivestreams.Publisher<? extends T>,long) is not applicable(cannot infer type-variable(s) T
(actual and formal argument lists differ in length))
method reactor.test.StepVerifier.<T>create(org.reactivestreams.Publisher<? extends T>,reactor.test.StepVerifierOptions) is not applicable
(cannot infer type-variable(s) T
(actual and formal argument lists differ in length))
This is the code I am trying to run:
#Test
void create() {
recommendationRepository.deleteAll();
RecommendationEntity given = RecommendationEntity.builder()
.recommendationId(BASE_RECOMMENDATION_ID)
.movieId(BASE_MOVIE_ID)
.content("Fake recommendation")
.build();
StepVerifier.create(recommendationRepository.save(given))
.expectNextMatches(recommendationEntity -> assertRecommendation(given, recommendationEntity))
.verifyComplete();
}
And repository looks like this:
public interface RecommendationRepository extends ReactiveCrudRepository<RecommendationEntity, String> {
Flux<RecommendationEntity> findByMovieId(int movieId);
}
Assuming that we have an object with the following attributes:
public class MyObject {
private String attr1;
private Integer attr2;
//...
public String getAttr1() {
return this.attr1;
}
public Integer getAttr2() {
return this.attr2;
}
}
One way of sorting a list mylist of this object, based on its attribute attr1 is:
mylist.sort(Comparator.comparing(MyObject::getAttr1));
Is it possible to use this code inside a method in a dynamic way and replace the getAttr1 part with a method that returns the getter of an attribute of the object based on its name? Something like:
public void sortListByAttr(List<MyObject> list, String attr) {
list.sort(Comparator.comparing(MyObject::getGetterByAttr(attr)));
}
The MyObject::getGetterByAttr(attr) part does not compile, I wrote it just as an example to explain my idea
I tried to implement a method with the following code new PropertyDescriptor(attr, MyObject.class).getReadMethod().invoke(new MyObject()) but It's still not possible to call a method with a parameter from the comparing method
You could add a method like
public static Function<MyObject,Object> getGetterByAttr(String s) {
switch(s) {
case "attr1": return MyObject::getAttr1;
case "attr2": return MyObject::getAttr2;
}
throw new IllegalArgumentException(s);
}
to your class, but the returned function is not suitable for Comparator.comparing, as it expects a type fulfilling U extends Comparable<? super U> and while each of String and Integer is capable of fulfilling this constraint in an individual invocation, there is no way to declare a generic return type for getGetterByAttr to allow both type and be still compatible with the declaration of comparing.
An alternative would be a factory for complete Comparators.
public static Comparator<MyObject> getComparator(String s) {
switch(s) {
case "attr1": return Comparator.comparing(MyObject::getAttr1);
case "attr2": return Comparator.comparing(MyObject::getAttr2);
}
throw new IllegalArgumentException(s);
}
to be used like
public void sortListByAttr(List<MyObject> list, String attr) {
list.sort(getComparator(attr));
}
This has the advantage that it also may support properties whose type is not Comparable and requires a custom Comparator. Also, more efficient comparators for primitive types (e.g. using comparingInt) would be possible.
You may also consider using a Map instead of switch:
private static Map<String,Comparator<MyObject>> COMPARATORS;
static {
Map<String,Comparator<MyObject>> comparators=new HashMap<>();
comparators.put("attr1", Comparator.comparing(MyObject::getAttr1));
comparators.put("attr2", Comparator.comparing(MyObject::getAttr2));
COMPARATORS = Collections.unmodifiableMap(comparators);
}
public static Comparator<MyObject> getComparator(String s) {
Comparator<MyObject> comparator = COMPARATORS.get(s);
if(comparator != null) return comparator;
throw new IllegalArgumentException(s);
}
More dynamic is only possible via Reflection, but this would complicate the code, add a lot of potential error source, with only little benefit, considering that you need only to add one line of source code for adding support for another property in either of the examples above. After all, the set of defined properties gets fixed at compile time.
You could also have a single place where this comparators would be defined:
static enum MyObjectComparator {
ATTR1("attr1", Comparator.comparing(MyObject::getAttr1));
MyObjectComparator(String attrName, Comparator<MyObject> comparator) {
this.comparator = comparator;
this.attrName = attrName;
}
private final Comparator<MyObject> comparator;
private final String attrName;
private static MyObjectComparator[] allValues = MyObjectComparator.values();
public static Comparator<MyObject> findByValue(String value) {
return Arrays.stream(allValues)
.filter(x -> x.attrName.equalsIgnoreCase(value))
.map(x -> x.comparator)
.findAny()
.orElseThrow(RuntimeException::new);
}
}
And your usage would be:
public void sortListByAttr(List<MyObject> list, String attr) {
list.sort(MyObjectComparator.findByValue(attr));
}
I am trying to create a class that abstracts the use of predicates from its end user.
My app uses Guava-Retrying extension which works great.
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(Predicates.<Boolean>isNull())
....
.build();
retryer.call(callable);
I can call easily call it with predicates and it polls until predicate returns false.
Now, maybe I misunderstand predicates but I am trying to create a class that will abstract them.
I wish to call it as follows
MyPoller.poll(new PollCondition<MyClass>() {
#Override public boolean condition() {
return !isValid(result**.getPermissions(), permissionName);
}
});
So I wrote PollCondition class as follows.
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition();
}
public abstract boolean condition();
}
but MyPoller.poll() call fail to compile - result is not declared.
Any idea?
It seems you don't understand predicates indeed. A predicate is a function that takes an input as argument, and returns a boolean value (usually based on the input, of course).
Let's examine your PollCondition class:
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition();
}
public abstract boolean condition();
}
So it defines an abstract condition() method that doesn't take anything as argument, and returns a boolean. And it can be "transformed" into a Predicate using getCondition(). This method returns a predicate which takes an input as argument (result), ignores it completely, and always returns the boolean returned by condition().
You then create a PollCondition using
new PollCondition<MyClass>() {
#Override public boolean condition() {
return !isValid(result.getPermissions(), permissionName);
}
}
That would be correct if, in the scope where you execute that code, there was a variable named result. But there is not. resultis in fact an input to your condition. So the class should in fact defined like this:
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition(result);
}
public abstract boolean condition(T result);
}
And you would then be able to instantiate one using
new PollCondition<MyClass>() {
#Override public boolean condition(MyClass result) {
return !isValid(result.getPermissions(), permissionName);
}
}
But I really, really don't see what that brings over using a simple Predicate directly.
Define MyPoller.poll() like this:
public poll(Predicate<T> predicate);
and use it like this:
MyPoller.poll(result -> !isValid(result.getPermissions(), permissionName));
I want to get a bean of a class A that implements Class B,
public class AndroidDeviceRule implements DeviceRule {}
this is fine
return (DeviceRule) context.getBean(myBeanName, DeviceRule.class);
But, I would prefer something like
return (DeviceRule) context.getBean(mybeanName, Class<? extends DeviceRule>);
But I can't..
- Syntax error on token ",", ( expected after
this token
- Syntax error on token(s), misplaced
construct(s)
I will recommend Autowiring bean for this
#Autowired
DeviceRule deviceRule;
Much cleaner approach
What you can do is to define the actual DeviceRule subtype as a generic type at the method level. You can have this in two flavors:
// with an explicit type passed in (as in your example)
<T extends DeviceRule> T getSpringBean(String name, Class<T> type) {
return (T) applicationContext.getBean(name, type);
}
// with no explicit type; will return whatever the caller expects,
// obviously resulting in a ClassCastException if the cast fails.
<T extends DeviceRule> T getSpringBean(String name) {
return (T) applicationContext.getBean(name);
}