3

I'm trying to write a function, so I can pass a function as a parameter, such as

public class HashFunction {
    private Function f;
    public HashFunction(Function f) {
        this.f=f;
    }
    public Integer hash(String s){
        return f(s);
    }
}

So I can write code like

new HashFunction(function(String s){ return s.charAt(0)+0; });

Like in javascript. How can I do this?

3

5 Answers 5

5

Unlike many other modern languages, currently java doesn't syntactically support "floating chunks of code" (known as closures).

However, the concept may be achieved through the use of anonymous classes, which are "on the fly" implementation declarations that typically implement an interface, but can also extend a class.


Here's how you would code your example in java:

public interface Hasher {
    int getHash(String s);
}

public class HashFunction {
    private Hasher f;
    public HashFunction(Hasher f) {
        this.f=f;
    }
    public Integer hash(String s){
        return f(s);
    }
}

then to use:

new HashFunction(new Hasher() {
    public int getHash(String s) {return s.charAt(0)+0;}
});
Sign up to request clarification or add additional context in comments.

8 Comments

++'s all round, but this was the answer with the details that helped me solve my problem.
Who downvoted this answer? Please explain how this answer is "not useful" (which is what a downvote indicates)
Your explanation is good, but I must pick the small nit: the fact that Java doesn't allow "floating chunks of code" is because it doesn't allow them, not because it is statically typed. C# is mostly statically typed, and it does allow delegates (strongly typed floating chunks of code), anonymous functions, and the lot--and that is all without using its "dynamic" escape hatch for integrating with more dynamic languages or libraries.
@SAJ14SAJ it is a small and incorrect nit. It is exactly because java is a statically typed language that is doesn't allow "closures"... They don't have a type!
Sorry, that is not true. C# is statically typed, and allows closures in version 4.0. They have a type. One example is Func<string> which matches things like the lamda (x) => "123" or string function x (). The fact is that Java's type system has no type representing closures or methods (other than the reflection stuff...), and certainly none where they are first class objects. Its not static versus non-static at issue. Static systems can handle it when they have the requisite first class types.
|
3

Passing functions as parameters is not possible in Java, unless they added it in a recent language change.

The Java pattern is to use so-called anonymous classes, which implement a member method which has the desired behavior.

For example, see:

http://docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm

or

How are Anonymous (inner) classes used in Java?

6 Comments

Wrong! Its not comfortable but you can do it. Use java.lang.reflection.method
I think "wrong" is too strong--completely bypassing all the natural patterns of the language is like saying you can construct a house from nothing but pencils and glue. Its true, but 2x4s and nails are so much better that they almost are not comparable. See my comment about the uses of reflections on the other answer above.
Reflection is a fundamental feature in java. That is the advabtage over c++.
I was once certified to teach C++ back in the mid-90s, when no one knew it, and all the modern layers of complexity had yet to be added. I cannot go back to C++, because it is like hauling water from the well, instead of using a faucet in the kitchen. Reflection is the least of its problems, at least in the problem domains I work in now, where fast creation of correct business logic is the win, not low-level hardware efficiency.
You have not understood reflection, or i have not undetstood your comment. Reflection is slow, it is the opposite of low level hardware. It is high level meta language. It is like a higher instance that can look at and into your code. And that all as base od the language.
|
2

I think you can use interface, the same way like Comparable or Comparator interface, or use annotation to mark some functions, and then use reflection to invoke them

Please check this

Comments

2

I can only second the other answers. Basically, it is not possible to pass real references to functions, like in JavaScript or Haskell, where "everything is a function".

However, if you want to have a little bit of "functional"-style programming in your code, take a look at the "Functional Java" library at http://functionaljava.org/

Maybe taking a look at Scala also can be helpful, as it runs in the JVM and is a very mature, upcoming and modern programming language. In Scala, you can pass functions and it would interoperate with your existing Java code, too. (There are functions, functors, monads, list comprehensions, ...)

3 Comments

I have dipped my toe in the functional programming waters, and terms like "functors", "monads" and such still scare me.... I think functional programming would be a lot more popular (it has so many advantages in many problem domains) if the language used to explain it were not so obscure. It all begins with lambda! :-) :-)
I think its a good idea to start with Haskell, because it contains a LOT of concepts used in many modern programming languages. learnyouahaskell.com is a good introduction at most of the things would work for Scala, too.
I am An Old Guy (TM). I learned functional programming for the first time with LISP back in thee 80s. :-) CAR and CDR are just as bad and obscure as lambda. But whomever decided that the word lambda should be lifted from the lambda calculus to DEFINE a new function instead of just using a normal word like "define" or maybe even "function" should be forced to eat Wheaties for breakfast every morning without sugar.
0

functions are called methods in java. And you can pass them!!!
But this is advanced java. Use java.lang.reflection.Method to pass a method.
But you will not happy with that technique.

2 Comments

I have to agree, using reflection to bypass the normal language methods cannot lead to a happy outcome. Reflection should always be limited to meta-language work. For example, its appropriate in an ORM to map objects to tables, or in a serialization implementation like a JSON converter. But using it for business-model work is the road to tears.
Yes! It make only sense for special purpose.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.