C ++ equivalent std :: bind in Java?

Is there a way to bind parameter parameters to function pointers in Java, as you can with std :: bind in C ++? What would be the Java equivalent of this type?

void PrintStringInt(const char * s, int n) { std::cout << s << ", " << n << std::endl; } void PrintStringString(const char * s, const char * s2) { std::cout << s << ", " << s2 << std::endl; } int main() { std::vector<std::function<void(const char *)>> funcs; funcs.push_back(std::bind(&PrintStringInt, std::placeholders::_1, 4)); funcs.push_back(std::bind(&PrintStringString, std::placeholders::_1, "bar")); for(auto i = funcs.begin(); i != funcs.end(); ++i){ (*i)("foo"); } return 0; } 
+6
source share
5 answers

This is as close as possible to line feed line by line; bind does not match 1: 1 with any Java construct;

 static void PrintStringInt(String s, int n) { System.out.println(s + ", " + n); } static void PrintStringString(String s, String s2) { System.out.println(s + ", " + s2); } interface MyCall { void fn(String value); } public static void main(String[] argv) { Vector<MyCall> funcs = new Vector<MyCall>(); funcs.add(new MyCall() { @Override public void fn(String value) {PrintStringInt(value, 4); }}); funcs.add(new MyCall() { @Override public void fn(String value) {PrintStringString(value, "bar"); }}); for(MyCall i : funcs){ i.fn("foo"); } } 
+2
source

I'm afraid not, but this code is an approach to simulate C ++ templates (bad):

 abstract class Printer<T> { final T value; Printer( T v ) { value = v; } public abstract void print( String s ); } class PrintStringInt extends Printer< Integer> { PrintStringInt( int v ) { super( v ); } @Override public void print( String s ) { System.out.printf( "%s, %d\n", s, value ); } } class PrintStringString extends Printer< String > { PrintStringString( String v ) { super( v ); } @Override public void print( String s ) { System.out.printf( "%s, %s\n", s, value ); } } public class BindTest { public static void main( String[] args ) { Printer<?>[] funcs = { new PrintStringInt( 4 ), new PrintStringString( "bar") }; for( Printer<?> p : funcs ) { p.print( "foo" ); } } } 

Outputs:

 foo, 4 foo, bar 
+2
source

From Java7 on, one could do the same with method handlers, for more details see the java.lang.invoke.MethodHandle class API document.

+1
source

You can create an anonymous class with a function of the desired signature that forwards calls to the original function.

Let's say you have the following functions:

 public class StringPrinter { public void printStringInt( String s, int n ) { System.out.println( s + ", " + n ); } public void printStringString( String s, String s2 ) { System.out.println( s + ", " + s2 ); } } 

You can then create anonymous classes that efficiently bind arguments to these functions.

 public static void main( String[] args ) { public interface Print1String { public void printString( String s ); } List<Print1String> funcs = new ArrayList<Print1String); funcs.add( new Print1String() { public void printString( String s ) { new StringPrinter( ).printStringInt( s, 42 ); }}); funcs.add( new Print1String() { public void printString( String s ) { new StringPrinter( ).printStringString( s, "bar" ); }}); for ( Print1String func : funcs ) { func.print1String("foo"); } } 
0
source

Use the Handle method, here is an example

 public class HW { int sum; public HW(int a, int b) { super(); this.sum = a+b; } public void hello1(double c) { double newnumber = sum+c; System.out.println("hello from hello1, new number= " + newnumber); } public void hello2() { System.out.println("hello from hello2, sum=" + sum); } } import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; public class TestMethodHandle { /** * @param args */ public static void main(String[] args) { HW hw = new HW(10, 15); MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandle mh; try { mh = lookup.findVirtual(HW.class, "hello2", MethodType.methodType(void.class)); mh.invoke(hw); mh = lookup.findVirtual(HW.class, "hello1", MethodType.methodType(void.class, double.class)); mh.invoke(hw, 20); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (Throwable e) { e.printStackTrace(); } } 
0
source

All Articles