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?

user1277170
  • 3,127
  • 3
  • 19
  • 19

5 Answers5

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;}
});
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • ++'s all round, but this was the answer with the details that helped me solve my problem. – user1277170 Nov 23 '12 at 01:03
  • Who downvoted this answer? Please explain how this answer is "not useful" (which is what a downvote indicates) – Bohemian Nov 23 '12 at 01:17
  • 1
    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 Nov 23 '12 at 01:26
  • @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! – Bohemian Nov 23 '12 at 03:41
  • Sorry, that is not true. C# is statically typed, and allows closures in version 4.0. They have a type. One example is Func 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. – SAJ14SAJ Nov 23 '12 at 04:13
  • I downvoted, for the exact reason @SAJ14SAJ stated. Remove that and I'll gladly upvote. Haskell and Scala are two other examples of statically typed languages that allow closures. – Blake Pettersson Nov 23 '12 at 16:02
  • @SAJ14SAJ Hmmm oops. I did some research... I was wrong! I've edited my answer accordingly. Thanks for the correction. – Bohemian Nov 23 '12 at 20:03
  • @BlakePettersson Hmmm oops. I did some research... I was wrong! I've edited my answer accordingly. Thanks for the correction. I learned somerthing :) – Bohemian Nov 23 '12 at 20:03
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?

Community
  • 1
  • 1
SAJ14SAJ
  • 1,698
  • 1
  • 13
  • 32
  • Wrong! Its not comfortable but you can do it. Use java.lang.reflection.method – AlexWien Nov 23 '12 at 01:24
  • 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. – SAJ14SAJ Nov 23 '12 at 01:28
  • Reflection is a fundamental feature in java. That is the advabtage over c++. – AlexWien Nov 23 '12 at 01:31
  • 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. – SAJ14SAJ Nov 23 '12 at 01:34
  • 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. – AlexWien Nov 23 '12 at 01:39
  • I meant that on the list of things C++ has or doesn't have that make it unsuitable to my problem domain, reflection is near the bottom--that is all. The problems are the way pointers work, the hideous syntax for references, the burdensome amount of ceremony to accomplish simple tasks, the horror that is the pre-processor and its implications, the gargantuan learning curve of the ugly APIs in the modern libraries, the lack of effective memory management (without one of those libraries), and so on. Reflection or its lack isn't even on the top ten. – SAJ14SAJ Nov 23 '12 at 01:44
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

Community
  • 1
  • 1
bhuang3
  • 3,493
  • 2
  • 17
  • 17
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, ...)

user3001
  • 3,437
  • 5
  • 28
  • 54
  • 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! :-) :-) – SAJ14SAJ Nov 23 '12 at 01:14
  • I think its a good idea to start with Haskell, because it contains a LOT of concepts used in many modern programming languages. http://learnyouahaskell.com/ is a good introduction at most of the things would work for Scala, too. – user3001 Nov 23 '12 at 01:16
  • 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. – SAJ14SAJ Nov 23 '12 at 01:22
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.

AlexWien
  • 28,470
  • 6
  • 53
  • 83
  • 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. – SAJ14SAJ Nov 23 '12 at 01:25
  • Yes! It make only sense for special purpose. – AlexWien Nov 23 '12 at 01:27