I want to create a #FunctionalInterface in Java which accepts both Streams or Optional types as a parameter. I tried to do this, but since they don't share a common interface it seems impossible to achieve. I also tried using a common wrapper class which invokes the #FunctionalInterface but since I need the type parameters at runtime it seems this isn't possible.
Minimum example:
#FunctionalInterface
public interface AcceptingInterface<S, T> {
T accept(S s);
}
public class Test<S, T> {
private final AcceptingInterface<S, T> funcInterface;
private final Class<S> source;
private final Class<T> target;
public Test(AcceptingInterface<S, T> a, Class<S> s, Class<T> t) {
this.funcInterface = a;
this.source = s;
this.target = t;
}
public T invoke(S s) {
return s == null ? null : this.funcInterface.accept(s);
}
public Class<S> getSource() {
return source;
}
public Class<T> getTarget() {
return target;
}
}
Maybe my approach is wrong... I would love to receive feedback and/or a solution to this problem.
I assume you want to treat an Optional as a Stream of 0-1 elements, in which case you can add a default method that translates from Optional to Stream, thusly:
#FunctionalInterface
public interface AcceptingInterface<V, T> {
T accept(Stream<? extends V> s);
default T accept(Optional<? extends V> opt){
return accept(opt.map(Stream::of).orElseGet(Stream::empty));
}
}
Java 9 is supposed to add an Optional.stream() method.
Related
I am currently learning about the functionalities of the Optional class, and I am trying to build a simplified version of the Optional class. I was able to code ifPresent(), filter(), of(), map() and so on. However, I am currently stuck with the implementing or().
I know that or() have the signature Optional<T> or(Supplier<? extends Optional<? extends T>> supplier). However, my implementation assumed that I can access the contents of the Optional. As show below:
class Optional<T> {
private final T item;
...
Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
if (this.item == null) {
T item = supplier.get().item;
return Maybe.<T>of(item);
} else {
return this;
}
}
}
As you can see, T item = supplier.get().item would throw an error saying that .item is inaccessible due to it being private. How am I able to access the item without causing this error?
First, you need to recall that you can not access a private field through an instance of a subtype, even though assigning the subtype reference to a variable of the current type, which allows the access, is possible without cast.
So if you have
public class ClassWithPrivateField {
private String field;
static class Subclass extends ClassWithPrivateField {}
void someMethod(Subclass obj) {
String s = obj.field; // does not work, you can't access field through Subclass
}
}
you may write
public class ClassWithPrivateField {
private String field;
static class Subclass extends ClassWithPrivateField {}
void someMethod(Subclass obj) {
ClassWithPrivateField withBroaderType = obj; // always works
String s = withBroaderType.field; // now, no problem to access field
}
}
Now to your more complicated generic variant. If you have
public class Optional<T> {
private final T item;
private Optional(T t) {
item = t;
}
Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
if(this.item == null) {
T item = supplier.get().item;
return Optional.of(item);
}
else return this;
}
private static <T> Optional<T> of(T item2) {
return new Optional<>(item2);
}
}
the access to item is rejected by the compiler because the type returned by the supplier is ? extends Optional<? extends T> which is a subtype of Optional<? extends T>, just the same way as Subclass is a subtype of ClassWithPrivateField.
You can fix the issue the same way, by introducing a variable:
public class Optional<T> {
private final T item;
private Optional(T t) {
item = t;
}
Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
if(this.item == null) {
Optional<? extends T> optional = supplier.get(); // valid assignment
T item = optional.item; // valid access
return Optional.of(item);
}
else return this;
}
private static <T> Optional<T> of(T item2) {
return new Optional<>(item2);
}
}
Alternatively, you could insert a type cast to Optional<? extends T> like
T item = ((Optional<? extends T>)supplier.get()).item;
but I would prefer the variant with a variable as it immediately shows to the reader that the assignment (without a cast) is a valid type transition which can never fail. The type cast can not fail either and is a no-op at runtime, but its syntax is indistinguishable from type casts performing a runtime check that could fail.
You just need to replace
T item = supplier.get().item;
return Maybe.<T>of(item);
with
return (Optional<T>)supplier.get();
I built a simple document store, there are entities that have fields of different types, I have a Float, Int and String type. The entity contains an array list of values, if someone updates the schema of the entity I would like to be able to try to convert the values to the new type.
public interface FieldType<T> {
ArrayList<T> values;
}
public class FloatField implements FieldType<Float> {
}
public class StringField implements FieldType<String> {
}
I have thought about using a abstract class with methods as below
public abstract class Field<T> implements FieldType<T> {
abstract public <T> castFromString(String value);
abstract public <T> castFromFloat(Float value);
abstract public <T> castFromInt(Int value);
}
public class FloatField extends Field<Float> {
#override
public <Float> castFromString(String value){
Float castValue = null;
try {
castValue = Float.parseFloat(value);
} catch(Exception e){
}
return castValue;
}
}
I did not really like this solution as I would have to add a new abstract method each time I added an extra type to the system.
Any ideas how I could implement this better?
Maybe you could use the Function<T, R> interface?
public abstract class Field<T> implements FieldType<T> {
...
public <F> T convert(F value, Function<F, T> converter) {
try {
return converter.apply(value);
} catch(Exception e) {
return null;
}
}
...
}
And then specify the converter using a lambda expression or a method reference:
field.convert("1234", BigDecimal::new); //with a method reference
field.convert("1234", s -> new BigDecimal(s)) //with a lambda
This would replace all of your convertXXX methods by one since the return type is inferred from the passed Function.
EDIT:
If you want automatic converting, you would of course have to hard-code these since you wouldn't want to write conversion methods for all 4240 classes in the Java API. This gets messy, though. Maybe something like this in a static helper class or in FieldType itself?
public class WhereverYouWantThis {
private static HashMap<Class<?>, HashMap<Class<?>, Function<?, ?>>> converters = new HashMap<>();
static {
putConverter(String.class, Float.class, Float::parseFloat);
}
private static <T, R> void putConverter(Class<T> t, Class<R> r, Function<T, R> func) {
HashMap<Class<?>, Function<?, ?>> map = converters.get(t);
if(map == null) converters.put(t, map = new HashMap<>());
map.put(r, func);
}
public static <T, R> Function<T, R> getConverter(Class<T> t, Class<R> r) {
HashMap<Class<?>, Function<?, ?>> map = converters.get(t);
if(map == null) return null;
#SuppressWarnings("unchecked")
Function<T, R> func = (Function<T, R>) map.get(r);
return func;
}
public static <T, R> R convert(T o, Class<R> to) {
#SuppressWarnings("unchecked")
Function<T, R> func = (Function<T, R>) getConverter(o.getClass(), to);
return func == null ? null : func.apply(o);
}
}
I don't think you need generics for this. Instead, just try to create a Float from the input String and return null if there be a problem:
public Float castFromString(String value) {
Float castValue = null;
try {
castValue = Float.parseFloat(value);
} catch(Exception e){
// log here
}
return castValue;
}
The reason I don't think generics are needed is that the types involved in the conversion are named/known in your helper methods.
This question already has answers here:
Get generic type of class at runtime
(30 answers)
Closed 7 years ago.
I'd like to find a hack to infer the actual generic instance of another instance's var in runtime, without:
Changing my needed method signature (adding the helper parameter Class<T>, the obvious way)
Having to instanceof all possible subtypes in a hardcoded way
MyInterface<? extends Number> myInterface = whateverReturnsWildcardDoubleInterface();
Class<?> type = inferInstanceType(myInterface);
assert type == Double.class;
/** This is the method that represents the code I am looking for with the conrete signature**/
public <T extends Number> Class<T> inferInstanceType(MyInterface<T> myInterface){
return T.class; //Concrete T (can or cannot be the very Number)
}
Ideally, it should return Double when T is particular subtype Integer,Double.. and Number when T is Number
I checked reflection, several "TypeResolver"/"GenericResolver" libs (as the one in Spring or others in Github), but I cannot fin a way to hack it.
EDIT: I reached the conclusion that he only feasible way to do that would be some kind of very complex reflection through the stack trace up to the acutal line that passes the type in the very instantiation
EDIT2: I know it's stupid... but I solved it by simply adding a T getT() method to my interface, so I could return myInterface.getT().getClass()
Disclaimer: This solution is provided as a hack tailored to my understanding of your setup, i.e. one generic interface with a single type parameter, multiple classes, which are not themselves generic, directly implementing this one interface alone, and implementing no other generic interfaces, directly or indirectly.
Assuming that all of the above is true, there is a relatively straightforward way of hacking a solution: calling getClass().getGenericInterfaces() returns a Type object that provides the actual type with which your generic interface has been instantiated.
interface MyInterface<T extends Number> {
T getVal();
}
class DoubleImpl implements MyInterface<Double> {
public Double getVal() {return 42.42; }
}
...
public static void main (String[] args) throws java.lang.Exception {
MyInterface<? extends Number> x = new DoubleImpl();
Type[] ifs = x.getClass().getGenericInterfaces();
System.out.println(ifs.length);
for (Type c : ifs) {
System.out.println(c);
Type[] tps = ((ParameterizedType)c).getActualTypeArguments();
for (Object tp : tps) {
System.out.println("===="+tp); // <<== This produces class java.lang.Double
}
}
}
Demo.
As assylias pointed out, Java's erasure will make that information unavailable at runtime - and thus a need for a hack.
On the assumption that myInterface has a getter for T, as in, MyInterface.getValue():T (or the hack would be to add it) you could do something like this (ignoring the possibility that getValue() could return null):
public <T extends Number> Class<T> inferInstanceType(MyInterface<T> myInterface){
return myInterface.getValue().getClass()
}
Below is the full implementation
public class Q34271256 {
public static interface MyInterface<T> {
T getValue();
}
public static class MyDoubleClass implements MyInterface<Double> {
private final Double value;
public MyDoubleClass(Double value) {
this.value = value;
}
#Override
public Double getValue() {
return value;
}
}
public static class MyIntegerClass implements MyInterface<Integer> {
private final Integer value;
public MyIntegerClass(Integer value) {
this.value = value;
}
#Override
public Integer getValue() {
return value;
}
}
#SuppressWarnings("unchecked")
public static <T extends Number> Class<T> inferInstanceType(MyInterface<T> myInterface){
Number value = myInterface.getValue();
if (value == null) return null;
return (Class<T>)value.getClass();
}
public static void main(String...args) {
List<MyInterface<? extends Number>> list = Arrays.asList(
new MyDoubleClass(1.1),
new MyIntegerClass(5)
);
for (MyInterface<? extends Number> myInterface : list) {
Class<?> type = inferInstanceType(myInterface);
System.out.printf("%s inferred type is %s\n",
myInterface.getClass().getName(),
type.getName());
}
}
}
And the output should look something like this:
MyDoubleClass inferred type is java.lang.Double
MyIntegerClass inferred type is java.lang.Integer
In several spots in my code I have ArrayLists and TreeSets whose generic type I wish to convert. So for example I have an ArrayList<Integer> which I wish to convert to an ArrayList<Long>. Or I have a TreeSet<BigInteger> which I wish to convert to a TreeSet<String>.
All of these conversions can be made, but then I have to create for each type conversion a different function. Therefore I want to create a generic function whose signature looks something like this:
public static <Q,T> Collection<Q> convert(Collection<T> col, Class<Q> Q)
What I want is to get the class from col (e.g. ArrayList), create a new collection of that class and type Q (called newCol), and then iterate through col and convert each element which is of type T to type Q and add it to newCol and lastly return newCol.
How can I do this?
There's no special mechanism like casting of incompatible classes in Java. You need to specify an explicit function which will perform a conversion. Using Java 8 it's really easy:
public static <Q,T,C extends Collection<Q>> C convert(Collection<T> col, Function<T, Q> fn,
Supplier<C> supplier) {
return col.stream().map(fn).collect(Collectors.toCollection(supplier));
}
Use it like this:
TreeSet<BigInteger> values = // fill them somehow
TreeSet<String> converted = convert(values, BigInteger::toString, TreeSet::new);
#Tagir Valeev is right. You can do it easily in Java 8. But if you use Java 7, you can try to do something like this:
public static <F, T> Collection<T> transform(Collection<F> fromCollection, Function<? super F, T> function) {
return new TransformedCollection<F, T>(fromCollection, function);
}
static class TransformedCollection<F, T> extends AbstractCollection<T> {
final Collection<F> fromCollection;
final Function<? super F, ? extends T> function;
TransformedCollection(Collection<F> fromCollection, Function<? super F, ? extends T> function) {
this.fromCollection = checkNotNull(fromCollection);
this.function = checkNotNull(function);
}
#Override public void clear() {
fromCollection.clear();
}
#Override public boolean isEmpty() {
return fromCollection.isEmpty();
}
#Override public Iterator<T> iterator() {
return Iterators.transform(fromCollection.iterator(), function);
}
#Override public int size() {
return fromCollection.size();
}
}
It's code from Guava library.
I have a simple interface:
interface Predicate<T> {
boolean accepts(T in);
}
Now I would also like to provide sth of the form:
interface Predicate<T> {
public static Predicate<T> ALL = new Predicate<T>(){ ... }
boolean accepts(T in);
}
This is not legal in the form presented above. Is there a way to provide a generic implementation that would be typed i.e. in multiple context I could say Predicate.ALL, a bit like Collections.EMPTY_SET?
UPDATE: I meant interface...
You could use type inference just like Collections.emptySet() (note that Collections.EMPTY_SET doesn't use generics).
From Collections:
public static final Set EMPTY_SET = new EmptySet();
public static final <T> Set<T> emptySet() {
return (Set<T>) EMPTY_SET;
}
You could mimic it like this:
public static Predicate ALL = new Predicate(){ ... }
public static final <T> Predicate<T> all() {
return (Predicate<T>) ALL;
}
you only need to replace <T> with something meaningful in the declaration of ALL. Or remove altogether - note, Collections.EMPTY_SET is of type Set, not Set<T>.
To start with, your simple class is invalid because accepts doesn't have an implementation nor is it abstract. Let's assume you meant to make it abstract, so that actual predicates are derived classes that override it. Then the ALL predicate is one that always returns true. But you can't make it a static field, because static fields cannot reference the type parameter.
public abstract class Predicate<T> {
public abstract boolean accepts(T in);
public static <T> Predicate<T> all() {
return new Predicate<T> { boolean accepts(T in) { return true; } };
}
}
There are two ways to implement the ALL predicate:
public interface Predicate<T> {
public static final Predicate<Object> ALL = new Predicate<Object> {
#Override public boolean accepts(Object in) { return true; }
}
boolean accepts(T in);
}
You are declaring a concrete class field (a constant) here, so you must use a concrete replacement for the type variable T. As you are not interested in the type, you use the supertype of all objects: java.lang.Object.
This implementation would satisfy the compiler to not generate any warning and is a good starting point. However, you have some difficulties. Consider this code:
public class PredicateTester {
public static void main(String[] args) {
test1(Predicate.ALL, "some string"); // compiler error
test2(Predicate.ALL, "some string");
}
public static void test1(Predicate<String> pred, String in) {
System.out.println(pred.accepts(in) ? "pass" : "fail");
}
public static void test2(Predicate<? super String> pred, String in) {
System.out.println(pred.accepts(in) ? "pass" : "fail");
}
}
Although test1 and test2 are both valid methods (and compile fine), the call to method test1 will not compile. Simply put: A Predicate<Object> is not a Predicate<String>.
Conclusion: You must remember the PECS (producer extends, consumer super) when designing your methods that will take a Predicate as an argument.
The other option is to just not provide a type at all:
public interface Predicate<T> {
#SuppressWarnings("rawtypes")
public static final Predicate ALL = new Predicate {
#Override public boolean accepts(Object in) { return true; }
}
boolean accepts(T in);
}
With that implementation the above mentioned class PredicateTester compiles just fine. So, this is the way to go.
In the form that you've written it you need it to be abstract as you're not providing the implementation of the accepts method.
abstract class Predicate<T> {
abstract boolean accepts(T in);
}
If you then want to provide a multi use "accept any" predicate you can do it like this:
public static Predicate ALL = new Predicate(){
#Override
boolean accepts(Object in) {
return true;
}
};
#SuppressWarnings("unchecked")
static final <T> Predicate<T> all(){ return (Predicate<T>)ALL;}
This mimics the way that Collections.EMPTY_SET and Collections.emptySet() work.
Note that Collections.EMPTY_SET (and Predicate.ALL) are not type-safe but Collections.emptySet() (and Predicate.all()) will infer the type they are being assigned to.