Java-like code (maps, function pointers) - java

I need to do something similar to the following code:
#include <iostream>
#include <map>
using namespace std;
typedef char (*intfunction)() ;
char a(){
return 'a';
}
char b(){
return 'b';
}
int main() {
map<char, intfunction> mapita;
mapita['a'] = &a;
mapita['b'] = &b;
cout << mapita['a']()
<< mapita['b']();
return 0;
}
As a matter of fact, I don't really have to much knowledge in Java, so I'm searching for some help with this.
Is there any possible way to simulate or do the same as the code above? I was seeing some examples with interfaces and so on, but couldn't make it work the same way.

Check out this code:
import java.util.HashMap;
import java.util.Map;
public class test2 {
interface Test {
public String method();
}
public static void main(final String[] arg) {
final Map<String, Test> map = new HashMap<String, Test>();
map.put("a", new Test() {
#Override
public String method() {
return "aaa";
}
});
map.put("b", new Test() {
#Override
public String method() {
return "bbb";
}
});
System.out.println(map.get("a").method());
System.out.println(map.get("b").method());
}
}

I would like to use OOP solution to implement the behavior you want.
IDEA
As your code illustrates that you want to call different method accorrding to different key.
This scene perfectly matches the Factory Design Pattern, So i create a factory returning the method instance based on the key passed in. Then i abstract the function to a interface BaseMethod. Then, you can create classes implementing the interface to achieve the same method signature when your business growing.
Need to be improve
the factory is not thread safe.
the interface, classes need to be in multiple files.
Code
import java.util.HashMap;
import java.util.Map;
interface BaseMethod {
public void run();
}
class HelloWoldMethod implements BaseMethod {
public void run() {
System.out.println("Hello world");
}
}
class MethodFactory {
private static MethodFactory ins = null;
private final static Map<String, BaseMethod> map = new HashMap<String, BaseMethod>();
private MethodFactory() {
map.put("hello", new HelloWoldMethod());
}
public static BaseMethod getMethod(String key) {
if (null == ins) {
ins = new MethodFactory();
}
return map.get(key);
}
}
public class Test {
public static void main(String [] args) {
BaseMethod ins = MethodFactory.getMethod("hello");
if (null != ins) {
ins.run();
} else {
System.out.println("no method found");
}
}
}

The only real potential solution I can think of would be a map of runnable objects:
public void doSomething() {...}
//elsewheres
Map<String, Runnable> map = new HashMap<>();
//Java 7
map.put("test", new Runnable() { doSomething(); });
//Java 8
map.put("test", () -> { doSomething(); });
Either that, or a class that implements a common interface for your object (if you need some returned value).

the syntax might be a bit off, but
import java.utils.HashMap;
class CharHolder {
private char myChar;
CharHolder( char someChar ) {
myChar = someChar;
}
char getChar() {
return myChar;
}
public static void main(String[] args) {
HashMap<Character, CharHolder> mapita = new HashMap<>();
mapita.put( 'a', new CharHolder('a') );
mapita.put( 'b', new CharHolder('b') );
System.out.println( mapita.get('a').getChar() + " " + mapita.get('b').getChar() );
}
}
the output should be:
a b

Related

Understanding the code flow: diamond operator and anonymous class

I learned that from Java 9 it's possible to use the diamond operator while creating an anonymous class only if the type argument is inferable
After that, I don't understand this code, it's from Java Generic Programming theory
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Main {
public static <T> Iterable<T> getIterable(T... elems) {
return new Iterable<T>() {
#Override
public Iterator<T> iterator() {
return new Iterator<>() {
int i = 0;
#Override
public boolean hasNext() {
return i < elems.length;
}
#Override
public T next() {
if(!hasNext()) throw new NoSuchElementException();
return elems[i++];
}
};
}
};
}
public static void main(String[] args) throws Exception{
String[] path = {"UP", "DOWN", "LEFT", "RIGHT"};
Iterable<String> ipaths = getIterable(path);
for (String apath : ipaths) {
System.out.println(apath);
}
}
}
I don't understand how this code work, I tried with debugger but it's still really strange to me, the first "return new Iterator()" in my IntellijIDEA is in grey, seems like it's treated like a comment
My knowledge about anonymous class is just a simple creation like that
Example ex = new Example() {
//fields
// no constructor
//method, overriden method from the superclass
};

Java, Object-independent null return

Given Java source code and a preprocessor (like C++), I would like to replace all mentions of null with a function that returns null. It finds a call to null and replaces it with the following function.
public static Object returnNull(){
return null;
}
This fails because there are varied classes and:
functionThatWantsCustomClass( returnNull() ); //Object cannot be converted to CustomClass
or
if( cc == returnNull() ) //Object cannot be converted to CustomClass
etc.
Easiest solution I can imagine is having to parametrize the preprocessor, although that would require going through every single null to add the parameter maually, eg: null/*CustomClass*/.
Another method is spending a lot of time writing a much better parser so it always knows the required class for a returnTypedNull() function.
Is there a way to get through this error with minimal modification/parsing?
Use generics:
public static <T> T returnNull() {
return (T) null;
}
Follow-up from comment
The following code is as close to comment as I can decipher, and it compiles fine:
public class Test {
public static void main(String[] args) {
CustomClass cc = new CustomClass();
if (cc != returnNull())
cc.errlog( returnNull() );
}
public static <T> T returnNull() {
return (T) null;
}
}
class CustomClass {
void errlog(Exception e) {
}
}
Now, if there are 2 errlog methods with only one non-primitive parameter:
class CustomClass {
void errlog(Exception e) {
}
void errlog(String s) {
}
}
Then it will fail with error The method errlog(Exception) is ambiguous for the type CustomClass, because the compiler doesn't know whether T should be Exception or String, i.e. which of the two to call.
You have to explicitly tell the compiler:
cc.errlog( Test.<Exception>returnNull() );
Use generics ant it will work.
Example:
public class ReturnNullExample {
public static void main(String[] args) {
ReturnNullExample example = new ReturnNullExample();
example.someMethod(ReturnNullClass.returnNull());
CustomClass cc = null;
if(cc == ReturnNullClass.returnNull()) {
System.out.println("cc is null");
}
cc = new CustomClass();
if(cc != ReturnNullClass.returnNull()) {
System.out.println("cc is not null");
}
}
public void someMethod(CustomClass customClass) {
System.out.println("This method does nothing");
}
}
class CustomClass {
private int number;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
class ReturnNullClass {
public static <T> T returnNull() {
return null;
}
}

How to accumulate the changes to an immutable object within a Java stream and get the final result when stream terminates

Is there any way to express the following code with Java 8 streams and lambdas?
ImmutableObject immutable = new ImmutableObject();
for(int i = 0; i < 10; i++) {
immutable = immutable.changeState(i);
}
return immutable;
ImmutableObject is just a trivial immutable object:
class ImmutableObject {
private final int state;
public ImmutableObject() {
this(0);
}
public ImmutableObject(final int state) {
this.state = state;
}
public ImmutableObject changeState(final int newState) {
return new ImmutableObject(newState);
}
}
I came up with this:
IntStream.range(0, 10).
mapToObj(i -> immutable.changeState(i)).reduce((a, b) -> b).get()
but the result for each iteration is discarded - I can't not assign the result back to immutable reference since it is inside a lamba expression and should be (effectively) final.
This is a perfect example of streams not being the answer to everything.
However, if you insists, here is a stream version, using collect() on a "holder" object, so the reference value can be updated.
It's a hack, it's ugly, but it'll work.
To make it an MCVE, I created a simple immutable sum implementation.
public class Test {
public static void main(String[] args) {
ImmutableObject o = IntStream.range(0, 10).collect(
() -> new ImmutableObject[] { new ImmutableObject(0) },
(h, i) -> h[0] = h[0].changeState(i),
(h1, h2) -> { throw new UnsupportedOperationException("Parallel not supported"); }
)[0];
System.out.println(o); // prints: 45
}
}
class ImmutableObject {
private final int v;
ImmutableObject(int v) { this.v = v; }
ImmutableObject changeState(int i) { return new ImmutableObject(this.v + i); }
#Override public String toString() { return Integer.toString(this.v); }
}
Let's do this step by step. First replace loop with stream.
private static Immutable immutable = new Immutable(0);
public static void main(String[] args) {
IntStream.range(0,10).forEach(i -> {
Immutable localImmutable = immutable.changeState(i);
System.out.println(localImmutable.toString());
});
}
it executes for i in 1..10 since range() has exclusive upper bound.
Next u want store reference to new instance of Immutable (ImmutableObject in your code). You can access in lambda (or any java closure in wider sense) only final (or effectively final) variables. Maybe you have heard that each lambda (or closure) has reference to its context. We can use this context to access static fields. Let's try it
private static Immutable immutable = new Immutable(0);
public static void main(String[] args) {
IntStream.range(0,10).forEach(i -> {
immutable = immutable.changeState(i);
System.out.println(immutable.toString());
});
}
Since context cannot change its effective final (in some languages - like groovy - you can choose different context by setting proper delegate). Last but not least lets get rid of static keyword. I ended up with example
import java.util.stream.IntStream;
public class Test {
private static class Immutable {
private static int counter = 0;
private final int id = ++counter;
private final int state;
public Immutable(int state) {
this.state = state;
}
public Immutable changeState(int i) {
return new Immutable(i);
}
#Override
public String toString() {
return "id: " + id + ", state: " + state;
}
}
private Immutable immutable = new Immutable(0);
public void run() {
IntStream.range(0,10).forEach(i -> {
immutable = immutable.changeState(i);
System.out.println(immutable.toString());
});
}
public static void main(String[] args) {
new Test().run();
}
}
If you want to loose the private field you can use instead
public static void main(String[] args) {
Optional<Immutable> last = IntStream.range(0,10).boxed()
.map(Immutable::new)
.reduce((a,b) -> b);
System.out.println(last.get());
}

How can I get data of different types from an anonymous class

I have an object that delegates some work to another object which is implementing an interface. Then, I am creating anonymous classes implementing this interface and I would like to get information from these.
Is it okay to use a final array with a size of one as a pointer to a primitve to share data with the anonymous class?
Here is a working example of what I mean :
public class ExampleClass
{
public static final int INVALID_VALUE = -1;
public static void main(final String[] args)
{
final int[] buffer = { INVALID_VALUE }; // buffer is created
final InterfaceA iaObject = new InterfaceA()
{
#Override
public void doStuff(final String paramA)
{
buffer[0] = paramA.length(); // buffer is filled in anonymous class
}
};
final ClassA objA = new ClassA(iaObject);
objA.doStuff("hello, world");
if (buffer[0] == INVALID_VALUE) // buffer is used
{
System.err.println("Invalid length !");
}
else
{
System.err.println("The length is : " + Integer.toString(buffer[0]));
}
}
public static class ClassA
{
private final InterfaceA iaObject;
public ClassA(final InterfaceA iaObject)
{
this.iaObject = iaObject;
}
public void doStuff(final String paramA)
{
this.iaObject.doStuff(paramA);
}
}
public static interface InterfaceA
{
void doStuff(String paramA);
}
}
Thanks
Suggestion: why not using a generic for an out parameter?
interface InterfaceA {
public <T> void doStuff( String paramA, Holder<T> holder );
}
class Holder<T> {
public T t;
}
Full example:
public class ExampleClass
{
public static final int INVALID_VALUE = -1;
public static void main(final String[] args)
{
final InterfaceA< Integer > iaObject = new InterfaceA< Integer >() {
#Override
public Integer doStuff( String paramA, Holder<Integer> holder ) {
return holder.value = paramA.length();
}
};
final ClassA<Integer> objA = new ClassA<>( iaObject );
int result = objA.doStuff("hello, world", new Holder<>( INVALID_VALUE ));
if( result == INVALID_VALUE ) {
System.err.println("Invalid length !");
}
else {
System.err.println("The length is : " + Integer.toString( result ));
}
}
public static class ClassA<T> {
private final InterfaceA<T> iaObject;
public ClassA( final InterfaceA<T> iaObject_ ) {
this.iaObject = iaObject_;
}
public T doStuff( final String paramA, Holder<T> holder ) {
return this.iaObject.doStuff( paramA, holder );
}
}
public static interface InterfaceA<T> {
public T doStuff( String paramA, Holder<T> resultHolder );
}
public static class Holder<T> {
public T value;
public Holder( T value_ ) {
value = value_;
}
}
}
If I understand the gist of your question, you're wondering if it is good design principle to use a final array as a wrapper to share memory between an anonymous inner class and its enclosing class.
In my experience, this is a pretty poor way of sharing data between two objects. It is probably wiser to declare your interface differently. Either return an object or use a generic to specify what type you expect back from your anonymous class.
I think one of the largest problems with your approach is the lack of encapsulation - your InterfaceA implementation uses some "global" data holder (the array), and there is no way to prevent that this array can be used elsewhere, which in turn could lead to all kinds of problems (race conditions or whatever).
A cleaner way would be the definition of some separate class (or interface) with a getInt()-method or something similar.

tagging methods and calling them from a client object by tag

I have been trying to figure out a way to tag several methods from my base class, so that a client class can call them by tag. The example code is:
public class Base {
public void method1(){
..change state of base class
}
public void method2(){
..change state of base class
}
public void method3(){
..change state of base class
}
}
A client class from a main() method will call each method of Base through a random instruction sequence:
public static void main(String[] args) {
String sequence = "ABCAABBBABACCACC"
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++){
char temp = sequence.charAt(i);
switch(temp){
case 'A':{aBase.method1(); break;}
case 'B':{aBase.method2(); break;}
case 'C':{aBase.method3(); break;} }
}
System.out.println(aBase.getState());
}
Now I wish to get rid of the switch statement altogether from the Client object. I am aware of the technique to replace switch by polymorphism, but would like to avoid creating a set of new classes. I was hoping to simply store those methods in an appropriate data structure and somehow tag them with a matching character from the sequence.
A map could easily store objects with value/key pairs which could do the job, (as I did here), or the command pattern, but since I don't want to replace those methods with objects, is there a different way perhaps, to store methods and have a client selectively call them?
Any advice is appreciated
Something like this?
public class Base {
private final Map<Character, Method> methods = new HashMap<Character, Method>();
public Base() throws SecurityException, NoSuchMethodException {
methods.put('A', getClass().getMethod("method1"));
methods.put('B', getClass().getMethod("method2"));
methods.put('C', getClass().getMethod("method3"));
}
public Method getMethod(char c) {
return methods.get(c);
}
public void method1() {}
public void method2() {}
public void method3() {}
}
and then
public static void main(String[] args) throws Exception {
String sequence = "ABCAABBBABACCACC";
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++) {
char temp = sequence.charAt(i);
aBase.getMethod(temp).invoke(aBase);
}
}
I would use annotations on the methods in question, allowing it to be marked as a "tagged method", and providing the tag string to use for that method.
From that point the implementation gets simpler; you can use reflection to iterate over a class' methods and inspect their annotations; perhaps do this statically at startup and populate a mapping from tag string to java.lang.reflect.Method.
Then when processing the command string, invoke the methods that correspond to each tag.
Edit: some example code:
import java.lang.annotation.*;
#Retention(RetentionPolicy.RUNTIME)
#interface TaggedMethod {
String tag();
}
Then in the base class:
public class Base {
#TaggedMethod(tag = "A")
public void method1(){
..change state of base class
}
#TaggedMethod(tag = "B")
public void method2(){
..change state of base class
}
#TaggedMethod(tag = "C")
public void method3(){
..change state of base class
}
}
...and in the client:
private static final Map<String, Method> taggedMethods = new HashMap<String, Method>();
// Set up the tag mapping
static
{
for (Method m : Base.class.getDeclaredMethods())
{
TaggedMethod annotation = m.getAnnotation(TaggedMethod.class)
if (annotation != null)
{
taggedMethods.put(annotation.tag(), m);
}
}
}
so that you can access this as:
public static void main(String[] args) throws Exception
{
String sequence = "ABCAABBBABACCACC"
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++)
{
String temp = sequence.substring(i,1);
Method method = taggedMethods.get(temp);
if (method != null)
{
// Error handling of invocation exceptions not included
method.invoke(aBase);
}
else
{
// Unrecognised tag - handle however
}
}
System.out.println(aBase.getState());
}
This code hasn't been compiled or tested, by the way... :-)
You could use Attributes for this, in C#. For Java, use annotations. Derive a class from the Attribute class, say, TagAttribute, and apply the attribute to the methods.
[global::System.AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class TagAttribute : Attribute
{
public TagAttribute(char value)
{
this.value = value;
}
private char value;
public char Value
{
get { return value; }
}
}
Apply the attribute to the methods:
public class MyClass
{
[Tag('A')]
public void Method1()
{ Console.Write("a"); }
[Tag('B')]
public void Method2()
{ Console.Write("b"); }
[Tag('C')]
public void Method3()
{ Console.Write("c"); }
}
Invoke the methods using reflection:
private static void CallTaggedMethod(MyClass instance, char value)
{
MethodInfo methodToCall = null;
// From the MyClass type...
Type t = typeof(MyClass);
// ...get all methods.
MethodInfo[] methods = t.GetMethods();
// For each method...
foreach (MethodInfo mi in methods)
{
// ...find all TagAttributes applied to it.
TagAttribute[] attributes = (TagAttribute[])mi.GetCustomAttributes(typeof(TagAttribute), true);
if (attributes.Length == 0)
// No attributes, continue.
continue;
// We assume that at most one attribute is applied to each method.
TagAttribute attr = attributes[0];
if (attr.Value == value)
{
// The values match, so we call this method.
methodToCall = mi;
break;
}
}
if (methodToCall == null)
throw new InvalidOperationException("No method to call.");
object result = methodToCall.Invoke(
// Instance object
instance,
// Arguments
new object[0]);
// 'result' now contains the return value.
// It is ignored here.
}
Call the CallTaggedMethod from your Main method:
static void Main(string[] args)
{
String sequence = "ABCAABBBABACCACC";
MyClass inst = new MyClass();
foreach(char c in sequence)
CallTaggedMethod(inst, c);
// The rest.
Console.ReadLine();
}
Here is my annotations Approach. You don't even need a Map of tags to methods if you are using annotations, just iterate over the sequence and lookup the method for that tag using reflection.
import java.lang.annotation.*;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Tag {
char value();
}
then:
public class Base {
StringBuilder state = new StringBuilder();
#Tag('A')
public void method1(){
state.append("1");
}
#Tag('B')
public void method2(){
state.append("2");
}
#Tag('C')
public void method3(){
state.append("3");
}
public String getState() {
return state.toString();
}
}
then
public final class TagRunner {
private TagRunner() {
super();
}
public static void main(String[] args) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Base b = new Base();
run(b, "ABCAABBBABACCACC");
System.out.println(b.getState());
}
private static <T> void run(T type, String sequence) throws
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
CharacterIterator it = new StringCharacterIterator(sequence);
Class<?> taggedClass = type.getClass();
for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
getMethodForCharacter(taggedClass, c).invoke(type);
}
}
private static Method getMethodForCharacter(Class<?> taggedClass, char c) {
for (Method m : taggedClass.getDeclaredMethods()) {
if (m.isAnnotationPresent(Tag.class)){
char value = m.getAnnotation(Tag.class).value();
if (c == value) {
return m;
}
}
}
//If we get here, there are no methods tagged with this character
return null;
}
}

Categories