In the following code you're able to apply any Function f (e.g., add, subtract, etc.). How do I do that through Java?
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
There are two major changes you'll need to make to this code to make it work in Java. First, you'll need to replace the STL-style iterators with Java-style iterators, which fortunately isn't too hard. Second, you'll have to change the use of a function pointer or functor parameter with an object of a different type, since Java does not support function pointers.
In Java, iterators are heavier than in C++ and encapsulate the full range they traverse, not just the start or end of that range. With a Java iterator, you use the .next() and .hasNext() methods to walk across the range.
As for the function parameter, you will probably need to create your own interface representing some object that can be called as a function. For example:
public interface Operation<T> {
void apply(T argument);
}
This interface is a generic parameterized on some type T saying what the argument type is, and then exports a function called apply() that applies the function.
Given this, a simple but naive way to replicate for_each would be to write
public static <T> forEach(Iterator<T> itr, Operation<T> op) {
while (itr.hasNext())
op.apply(itr.next());
}
The reason I say that this is naive is that it doesn't use bounded wildcards correctly to expand the scope of where it can be used. A more proper version that's more Java-friendly would be this:
public static <T> forEach(Iterator<T> itr, Operation<? super T> op) {
while (itr.hasNext())
op.apply(itr.next());
}
Consult a reference on Java genetics for why this works.
Hope this helps!
To implement the template class you'd use Java Generics
For the callback, more than likely you'd want to create an Interface and pass an object that implemented it to the Generic class where you'd call the method defined therin.
You should use interfaces, but if you want to do it in the hard way, using reflection (not tested, not exception-checked, etc. But you can get the idea):
public void myFunction(Collection items, String methodName) {
foreach(Object o : items) {
Method method = o.getClass().getMethod(methodName);
method.invoke(o);
}
}
With good OO design, first through last would be objects of a specific (implements an interface) type and f() would take an object of that type (interface) as a parameter so you are done--it's pretty much like you wrote.
if you are talking about doing it on primitives instead then it's going to need generics, but at this point you'd want to look for a better design or better way to do that.
You didn't really give enough info for a more detailed answer, if we knew more about the problem you were trying to solve and the restrictions we might be able to give better advice.
Related
I need to write a class with function like this
class Converter <T>{
public <R> R convertBy(Function<T,?>... args){
Function<T,?> function = args[0];
// doing something
return function.apply(t);
}
}
I need this method to be type safe i.e first Function need from args needs to have the same argument type as this class type. For example, if my Converter would be Converter<String> I need to check (at the compile time) if the first function has String parameter.
Also, when I wrote method like that is saying that it returns object, and I cannot do
int a = converter.convertBy(func1,func2);
because is saying that Object is not convertible to int.
-- Edit
Maybe with bigger picture will be easier to get what is it about. So the meaning of convertBy function is that it can with easy combine diffrent operation on different types.
This is working, when I define function like
public <R> R convertBy(Function... args)
but then It is not type safe. What I need, is to make sure If my Converter is 'Converter ' user cannot pass as first parametr function like
Function func = (string)->{ return (String)string.length();}
Also I cannot change paramters from
convertBy(Function... args)
to
convertBy(Function first, Function... rest)
edit.
Well I what appeared later is that I can do that. But it still doesn't check.
Thank You.
The way to make sure at compile time that your Function has return type R is to declare it as Function<T,R>.
If you also want to accept an unspecified number of other functions with different types, you could write your function like this:
public <R> R convertBy(Function<T,R> first, Function<?,?>... others)
That way the return type matches the return type of the first function.
But without knowing what you're trying to do with those other functions, it is hard to know what types they are supposed to have.
You could make it without varargs quite easily actually, all you need to do is to make several methods with different amount of functions in those. This approach is often used for optimization anyway, as varargs aren't nearly as optimized as normal methods.
<R> R convertBy(Function<T, R> fnc);
<R,U> R convertBy(Function<T, U> fnc1, Function<U, R> fnc2);
// etc.
You can't ensure type safety in an array of Function, that is just impossible task. You lose type information there, and the best you could do would be checking the type using reflections, which happens at runtime, thus type safety is not checked compile time.
So I advise just sticking to the andThen or compose methods unless you have plenty functions and the utility brings you enough syntax sugar to be worth doing it that way.
I have a method call in a loop currently that does not compile:
for (Example example : Util.getExample(List.class)) {
// Do something with example
}
Util:
public class Util {
public <T> T getExample(Class<T> clazz) {
//...
}
}
The obvious fix is to cast the return from getExample to List<Example>. I'm wondering: is there is an alternative way to avoid the cast?
Further Information:
Posters asked for more information, so here goes...
I have built a framework around annotation processing that writes code to access and mutate class members (constructors, fields and methods). This framework backs both Parceler and Transfuse and allows me to, during compilation, identify a property and generate code to access or modify said property. For private properties (private constructors, private fields, private methods) I use a utility to perform these actions (Parceler's, Transfuse's) to break encapsulation via reflection.
Parceler has a feature to unroll collections during serialization in order to serialize members of the given collection. For private collections the InjectionUtil is used to access these properties within a loop:
for (Example example : InjectionUtil.getField(List.class, Container.class, container, "exampleField")) {
// ...
}
Which is the bug I'm currently faced with, and thus, why I'm asking about avoiding a cast. I'd prefer to not cast as I'd like to generically generate a bit of code to access a type and respect Java generics in the process.
If your getExample method is supposed to always return a list, then yes, change its return type to List<T>. But since you're passing List.class as an argument, it looks like you want to have a method that can return both lists and non-lists depending on which class object you pass it.
If so, that's not going to work the way you might be hoping. Your method in this case returns just List, the raw type. To make it return List<Example>, you'd have to pass it something like a hypothetical List<Example>.class, but there's no such thing. Generic type parameters are erased at compile time, so List<Example> and List<String> are really both the same class; they don't have separate class objects, so a class object argument can't tell your method what kind of list it should return.
You'll probably need to try a different design approach. Since this is clearly a simplified example, you might be able to get more help if you post more details about what you're actually trying to accomplish.
Guava's TypeToken can be used in this case because List<Foo>.class is not valid. TypeToken is used by creating an anonymous class. Because anonymous classes keep their generic signatures, this works.
for (Example foo : Util.getExample(new TypeToken<List<Example>>() {}) {
// do stuff
}
// utils
public <T> T getExample(TypeToken<T> typeToken) {
Type type = typeToken.getType();
// get example
}
TypeToken is more specific than just using the Class. You could also use the plain Type as a parameter so you can still feed it a Class. This is how Gson does it.
I think this is a design issue...
Since the method in Util you are calling is called getExamples it seems reasonable that it might just as well be fixed to return some collectionwhose elements are instance of the Example class.
It is reasonable to change getExamples to something like this?:
class Util {
public static <C extends Collection<? supper Example>> getExamples(final Supplier<C> factory) {
final C result = factory.get();
// here goes the code that adds the examples to the result collection
// using add or addAll.
return result;
}
}
So for-example if you wan to get a List<Example> using ArrayList<E> for implementation you would do like so:
List<Example> examples = Util.getExamples(ArrayList<Example>::new);
Try to pass the returned collection class object reference instead (eg. List.class, ArrayList.class) won't work as the code in getExamples will have a hard time (a) figuring out how to call the appropriate constructor using reflexion to instantiate the result (kinda of impossible if you pass just an interface class object such as List.class) and (b) casting the return from a raw type into a generic type with Example as element type. The latter is trivial however it is not as neat as it can be as it will generate a warning.
It is just more straight forward to delegate in the using code to indicate explicitly how to instantiate the result collection.
If you break away from returning a Collection and use methods like add and addAll in getExamples then perhaps you should borrow the Collectors framework from the java stream API.
Referring to : Wildcard Capture Helper Methods
It says to create a helper method to capture the wild card.
public void foo(List<?> i) {
fooHelper(i);
}
private <T> void fooHelper(List<T> l) {
l.set(0, l.get(0));
}
Just using this function below alone doesn't produce any compilation errors, and seems to work the same way. What I don't understand is: why wouldn't you just use this and avoid using a helper?
public <T> void foo(List<T> l) {
l.set(0, l.get(0));
}
I thought that this question would really boil down to: what's the difference between wildcard and generics? So, I went to this: difference between wildcard and generics.
It says to use type parameters:
1) If you want to enforce some relationship on the different types of method arguments, you can't do that with wildcards, you have to use type parameters.
But, isn't that exactly what the wildcard with helper function is actually doing? Is it not enforcing a relationship on different types of method arguments with its setting and getting of unknown values?
My question is: If you have to define something that requires a relationship on different types of method args, then why use wildcards in the first place and then use a helper function for it?
It seems like a hacky way to incorporate wildcards.
In this particular case it's because the List.set(int, E) method requires the type to be the same as the type in the list.
If you don't have the helper method, the compiler doesn't know if ? is the same for List<?> and the return from get(int) so you get a compiler error:
The method set(int, capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (int, capture#2-of ?)
With the helper method, you are telling the compiler, the type is the same, I just don't know what the type is.
So why have the non-helper method?
Generics weren't introduced until Java 5 so there is a lot of code out there that predates generics. A pre-Java 5 List is now a List<?> so if you were trying to compile old code in a generic aware compiler, you would have to add these helper methods if you couldn't change the method signatures.
I agree: Delete the helper method and type the public API. There's no reason not to, and every reason to.
Just to summarise the need for the helper with the wildcard version: Although it's obvious to us as humans, the compiler doesn't know that the unknown type returned from l.get(0) is the same unknown type of the list itself. ie it doesn't factor in that the parameter of the set() call comes from the same list object as the target, so it must be a safe operation. It only notices that the type returned from get() is unknown and the type of the target list is unknown, and two unknowns are not guaranteed to be the same type.
You are correct that we don't have to use the wildcard version.
It comes down to which API looks/feels "better", which is subjective
void foo(List<?> i)
<T> void foo(List<T> i)
I'll say the 1st version is better.
If there are bounds
void foo(List<? extends Number> i)
<T extends Number> void foo(List<T> i)
The 1st version looks even more compact; the type information are all in one place.
At this point of time, the wildcard version is the idiomatic way, and it's more familiar to programmers.
There are a lot of wildcards in JDK method definitions, particularly after java8's introduction of lambda/Stream. They are very ugly, admittedly, because we don't have variance types. But think how much uglier it'll be if we expand all wildcards to type vars.
The Java 14 Language Specification, Section 5.1.10 (PDF) devotes some paragraphs to why one would prefer providing the wildcard method publicly, while using the generic method privately. Specifically, they say (of the public generic method):
This is undesirable, as it exposes implementation information to the caller.
What do they mean by this? What exactly is getting exposed in one and not the other?
Did you know you can pass type parameters directly to a method? If you have a static method <T> Foo<T> create() on a Foo class -- yes, this has been most useful to me for static factory methods -- then you can invoke it as Foo.<String>create(). You normally don't need -- or want -- to do this, since Java can sometimes infer those types from any provided arguments. But the fact remains that you can provide those types explicitly.
So the generic <T> void foo(List<T> i) really takes two parameters at the language level: the element type of the list, and the list itself. We've modified the method contract just to save ourselves some time on the implementation side!
It's easy to think that <?> is just shorthand for the more explicit generic syntax, but I think Java's notation actually obscures what's really going on here. Let's translate into the language of type theory for a moment:
/* Java *//* Type theory */
List<?> ~~ ∃T. List<T>
void foo(List<?> l) ~~ (∃T. List<T>) -> ()
<T> void foo(List<T> l) ~~ ∀T.(List<T> -> ()
A type like List<?> is called an existential type. The ? means that there is some type that goes there, but we don't know what it is. On the type theory side, ∃T. means "there exists some T", which is essentially what I said in the previous sentence -- we've just given that type a name, even though we still don't know what it is.
In type theory, functions have type A -> B, where A is the input type and B is the return type. (We write void as () for silly reasons.) Notice that on the second line, our input type is the same existential list we've been discussing.
Something strange happens on the third line! On the Java side, it looks like we've simply named the wildcard (which isn't a bad intuition for it). On the type theory side we've said something _superficially very similar to the previous line: for any type of the caller's choice, we will accept a list of that type. (∀T. is, indeed, read as "for all T".) But the scope of T is now totally different -- the brackets have moved to include the output type! That's critical: we couldn't write something like <T> List<T> reverse(List<T> l) without that wider scope.
But if we don't need that wider scope to describe the function's contract, then reducing the scope of our variables (yes, even type-level variables) makes it easier to reason about those variables. The existential form of the method makes it abundantly clear to the caller that the relevance of the list's element type extends no further than the list itself.
I am refreshing my knowledge on Java generics. So I turned to the excellent tutorial from Oracle ... and started to put together a presentation for my coworkers. I came across the section on wildcards in the tutorial that says:
Consider the following method, printList:
public static void printList(List<Object> list) {
...
The goal of printList is to print a list of any type, but it fails to achieve that goal — it prints only a list of Object instances; it cannot print List<Integer>, List<String>, List<Double>, and so on, because they are not subtypes of List<Object>. To write a generic printList method, use List<?>:
public static void printList(List<?> list) {
I understand that List<Object> will not work; but I changed the code to
static <E> void printObjects(List<E> list) {
for (E e : list) {
System.out.println(e.toString());
}
}
...
List<Object> objects = Arrays.<Object>asList("1", "two");
printObjects(objects);
List<Integer> integers = Arrays.asList(3, 4);
printObjects(integers);
And guess what; using List<E> I can print different types of Lists without any problem.
Long story short: at least the tutorial indicates that one needs the wildcard to solve this problem; but as shown, it can be solved this way too. So, what am I missing?!
(side note: tested with Java7; so maybe this was a problem with Java5, Java6; but on the other hand, Oracle seems to do a good job regarding updates of their tutorials)
Your approach of using a generic method is strictly more powerful than a version with wildcards, so yes, your approach is possible, too. However, the tutorial does not state that using a wildcard is the only possible solution, so the tutorial is also correct.
What you gain with the wildcard in comparison to the generic method: You have to write less and the interface is "cleaner" since a non generic method is easier to grasp.
Why the generic method is more powerful than the wildcard method: You give the parameter a name which you can reference. For example, consider a method that removes the first element of a list and adds it to the back of the list. With generic parameters, we can do the following:
static <T> boolean rotateOneElement(List<T> l){
return l.add(l.remove(0));
}
with a wildcard, this is not possible since l.remove(0) would return capture-1-of-?, but l.add would require capture-2-of-?. I.e., the compiler is not able to deduce that the result of remove is the same type that add expects. This is contrary to the first example where the compiler can deduce that both is the same type T. This code would not compile:
static boolean rotateOneElement(List<?> l){
return l.add(l.remove(0)); //ERROR!
}
So, what can you do if you want to have a rotateOneElement method with a wildcard, since it is easier to use than the generic solution? The answer is simple: Let the wildcard method call the generic one, then it works:
// Private implementation
private static <T> boolean rotateOneElementImpl(List<T> l){
return l.add(l.remove(0));
}
//Public interface
static void rotateOneElement(List<?> l){
rotateOneElementImpl(l);
}
The standard library uses this trick in a number of places. One of them is, IIRC, Collections.java
Technically, there is no difference between
<E> void printObjects(List<E> list) {
and
void printList(List<?> list) {
When you are declaring a type parameter, and using it only once, it essentially becomes a wildcard parameter.
On the other hand, if you use it more than once, the difference becomes significant. e.g.
<E> void printObjectsExceptOne(List<E> list, E object) {
is completely different than
void printObjects(List<?> list, Object object) {
You might see that first case enforces both types to be same. While there is no restriction in second case.
As a result, if you are going to use a type parameter only once, it does not even make sense to name it. That is why java architects invented so called wildcard arguments (most probably).
Wildcard parameters avoid unnecessary code bloat and make code more readable. If you need two, you have to fall back to regular syntax for type parameters.
Hope this helps.
Both solutions are effectively the same, it's just that in the second one you are naming the wildcard. This can come handy when you want to use the wildcard several times in the signature, but want to make sure that both refer to the same type:
static <E> void printObjects(List<E> list, PrintFormat<E> format) {
I'm learning programming in java using generic types and got a probably very basic question.
Where's the difference between the further two snippets?
1.)
public void build(House house) {
// work only with house objects that extending House
}
2.)
public <T extends House> void build(T house) {
// work only with house objects that extending House
}
There is no difference between these two methods with respect to what they can take in as parameters; however, in the latter example, one does have access to the specific type T. Regardless, this example does not illustrate the power of generics.
As an example consider a LinkedList of Node<T> objects. We can define a wrapper, Node<T>, which can hold an object of any type. This is a very useful construct, as it allows us to write one piece of code that can be used for many different objects.
The difference is that inside the second function you have access to type type T, the type the caller used to access your method.
I can't think however of any way to use that type that would differ meaningfully from using House directly. It might make a difference with some other parameters or return types of the method.
They are logically the same.
Although, on the second case the compiler can make some advanced verifications.
Let´s say there is are two subclasses of House called XHouse and YHouse.
We have the following source code:
XHouse house = build(yHouse)
This will fail if yHouse is an object of type YHouse and YHouse is not a subclass of XHouse.
Think of a generic as a sort of template. When you fill the generic argument, you sort of create a new method. In the example above, the usage of the generic method is virtually creating the following:
public XHouse void build(XHouse house) {
// work only with XHouse objects that extending XHouse
}
Notice I even changed the comments.