I am coming from PHP to Java and I have some questions about "dynamic" functions.
Kinda like in php where you can do an include(VARNAME.".php"); and if varname is a it'll include a.php if its x it'll include x.php.
I wanna do that in Java but with functions.
Kinda like I have a varname and I want to include a function. So if varname is Test it'll include test() but I have a bunch of functions and its a nuisance to do
if(varname == "x"){ x(); }.
Is there any easy way to do it?
First off, if(varname == "x") is surely not what you want. This is a common Java mistake and will check the object identity, not the object value. You want if(varname.equals("x")).
Second, this isn't very idiomatic Java. As Jason pointed out, you can use reflection to do a dynamic method look-up. However, there is almost certainly a better design for what you are trying to accomplish.
Java is a very different language from PHP. Trying to apply PHP idioms to Java will only cause you pain and suffering.
Having said all that, I think this is roughly the code you are looking for:
Method method = this.class.getDeclaredMethod("x", new Class[] {});
method.invoke(this, new Object[] {});
If your varname equates to a function on the class you are in, you could theoretically use reflection to accomplish this. See this article from Sun/Oracle for more details
Related
Lets say I have an array movies = get_movies()
In ruby I often do
movies.map {|movie| movie.poster_image_url } or somesuch.
What can I do that is similar in Java? And by similarly elegant and terse and readable. I know there are a bazillion ways I can do this but if there's a nice way to do this that will make me not want to use Groovy or something let me know. I'm sure Java has some awesome ways to do things like this.
This is my Java code so far using TheMovieDB API Java wrapper from https://github.com/holgerbrandl/themoviedbapi/.
TmdbMovies movies = new TmdbApi(BuildConfig.MOVIEDB_API_KEY).getMovies();
MovieResultsPage results = movies.getPopularMovieList("en", 1);
// The following line is RubyJava and needs to your help!
results.getResults().map {|e| e.getPosterPath() };
// or ... more RubyJava results.getResults().map(&:getPosterPath());
A little more about #map/#collect in Ruby in case you know a lot of Java, but aren't familiar with ruby. http://ruby-doc.org/core-1.9.3/Array.html#method-i-collect
Closest thing I've seen to answering this from some quick browsing so far... https://planet.jboss.org/post/java_developers_should_learn_ruby
These look close, too. http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
So many options: Functional Programming in Java
This is Android as well... Anything good things that are available for Android devs out of the box and make this kind of programming easy? This is a functional programming style, right?
--
After getting replies with really good insights like: 'there is nothing wrong with a for loop' and (basically) 'syntax isn't everything', I am deciding that I will not try to make all my Java look like Ruby! I read this and then imagined an alternate future where 'future me' made a whole bunch of bad style decisions: https://github.com/google/guava/wiki/FunctionalExplained. <-- (A good read. TL;DR 'when you go to preposterous lengths to make your code "a one-liner," the Guava team weeps')
There's the map method on streams which takes a method argument.
collection.stream()
.map(obj -> obj.someMethod())
.collect(Collectors.toList()));
map returns another stream so in order to retrieve the list you have call the collect method.
Too much to explain in a post, but you can visit this link which helped me out a lot:
http://winterbe.com/posts/2014/03/16/java-8-tutorial/
I think (a collections class).foreach() is what you want, requires java8, and often makes use of lambda expressions to implement the class that fulfills the required input for the 'foreach()' method.
http://www.mkyong.com/java8/java-8-foreach-examples/
To address your change to that this is Android, then NO, you WILL NOT get java8 class changes such as .foreach(), you CAN get lambda expressions by making use of the retrolambda android variant. But this only gives you some Java8 'syntax' not 'classes', you won't get access to the Streams classes either.
I was wondering if this would work. In java, you use 'null' to make something nothing. Would this work?
Object nil = null;
Could I then use nil instead of null? Thanks!
Java doesn't allow for this.
However, if you want to achieve this sort of syntax whilst being able to run your code on a JVM (and with other Java code), you could look at Groovy, which has operator overloading (and with which you could also use DSLs for short syntax which would have similar effects to using custom operators).
Note that defining custom operators (not just overloading) is a big deal in any language, since you would have to be able to alter the lexer and grammar somehow.
I'm converting some python code to java, and have a situation where I need to call methods of an object but don't know which methods until runtime. In python I resolve this by using getattr on my object and passing it a string that is the name of my method. How would you do something similar in Java?
Class.getField is your friend. It probably won't be very straightforward though since Python is dynamically typed and Java is statically typed (unless you know the types of your fields in advance.)
EDIT: How to translate these examples. http://effbot.org/zone/python-getattr.htm
Attribute Lookup
Python
//normal
value = obj.attribute
//runtime
value = getattr(obj, "attribute")
Java
//normal
value = obj.attribute;
//runtime
value = obj.getClass().getField("attribute").get(obj);
Method Call
Python
//normal
result = obj.method(args)
//runtime
func = getattr(obj, "method")
result = func(args)
Java
//normal
result = obj.method(args);
//runtime
Method func = obj.getClass().getMethod("method", Object[].class);
result = func.invoke(obj, args);
In the simpler cases, you need to know whether you have a field or a method. esp as they can have the same name. Additionally methods can be overloaded, so you need to know which method signature you want.
If you don't care which method or field you get, you can implement this as a helper method fairly easily.
You can start here to learn about Java Reflection.
You can use java reflection but there is no exact equivalent of getattr.
In Java you do this with the Reflection API (and it's usually pretty cumbersome).
MethodUtils in Apache Commons BeanUtils project may make it a bit easier to work with, though it's a pretty hefty dependency for something simple like this.
You should use the Reflection API. Since the pure API is a bit ... unapproachable, you should have a look at helpers like commons beanutils or reflections.
The easiest way to handle this is to create a Map object in Java class & keep adding the name value pairs & retrieve it accordingly though it might not support different types that setAttr supports.
In AS3 I can write this["foo"] for access to a variable foo. I can construct any string in brackets. Is there a way to do this in Java?
You can use Java's reflection API to achieve the same effect, albeit much less elegantly. See here for a tutorial.
No, you can't do this. But you don't need to. There's an easier way to call variables. You just need to use this.foo to refer to the variable. Now, if you're trying to do something like
String var = "foo";
this[var] = "something else";
You may be able to do that with java reflection, but it would have quite a bit of overhead and I believe it would be quite inefficient.
No. If you want such kind of access, you should consider using Set interface (or reflection api, as noted before me).
I'm looking an efficient way of executing Haskell functions from within a Java program. I've considered the use of exec() to interact with GHC, but it seems like there should be a better method.
I usually avoid JNI-type approaches to linking across runtimes/languages. They just have too many gotchas and little upside. I find it easier to work across process boundaries. While I've never tried it with Haskell and Java, they both have libraries that support XML RPC, and it sounds like a natural fit for what you're doing. So: set up a Haskell program as a "service" and just call its functions when you need them.
I assume you know how to call C from Java? If so, then you can follow the FFI guide to call Haskell from C, and C from Java, creating a bridge. This is a native call, and may require some fiddling with linkers.
Details on calling Haskell from C are here: http://www.haskell.org/haskellwiki/Calling_Haskell_from_C
Alternatively, you might consider an RPC server.
Easiest way I can think of: start up hint in a separate process. As a quick demonstration, something dumb like
import Control.Monad
import Language.Haskell.Interpreter
main = getContents >>= mapM_ (eval >=> print) . lines
can be fed expressions on stdin and will give stringy results on stdout. Of course, it'll take a little more work to make sure this is safe.
(Err, assuming Java has some sort of popen2-ish functionality. Otherwise maybe you can do the same over sockets.)