How to use Java Generics for returing T from String

Black_Rider

I am trying to use Java generics for my particular use case. There is a Generic Class Node and there will be a lot of implementing class like NodeBoolean in this example.

public abstract class Node<T>
    {
        T defaultValue;

        public Node(T defaultValue) {
            this.defaultValue = defaultValue;
        }

        protected abstract T parse(String input) ;
        public T getValue()
        {
            try
            {
                // here will be some logic to get String value from some db or any other source
                String input = "true";
                return parse(input);
            } catch (Exception e) {
                return defaultValue;
            }
        }
    }

Implementing Class

class NodeBoolean extends Node<Boolean>
{
    public NodeBoolean(Boolean defaultValue) {
        super(defaultValue);
    }

    @Override
    protected Boolean parse(String input) {
        return Boolean.parseBoolean(input);
    }
}

Test Class

class TestNode
{
    public static void main(String[] args) {
        NodeBoolean node =  new NodeBoolean(true);
        System.out.println(node.getValue());
    }
}

Problems I am facing with this approach

  1. Suppose there are multiple variants of Constructor of class Node then all Implementing class also need to define them for visibility. This problem can be solved using Builder pattern but I am just wondering other possible solutions.

  2. There will be a lot of implementing class with having only one override method parse. I am looking for a way to define all different parsers based on instanceof of defaultValue in given example in generic class Node itself. And then this Node class not be abstract.

  3. I want to give functionality to define parse method which takes String and based on the user requirement return T value of it while creating object of Node class itself. By this way if I have only one occurrence of specific object type of Node can be created without defining any new Implementing class.

I am looking for a solution which solves above 3 problems. If I am not clear at any point then let me know.

Steve Chaloner
  1. I think exposing the constructors, or using the builder or factory patterns are the only possibilities here. But, this can be mitigated by the next answer.

  2. Instead of having the parse method as abstract, why not pass a function into the node that handles the parsing?


public class Node<T> {
    private T defaultValue;
    private Function<String, T> parser;

    public Node(T defaultValue,
                Function<String, T> parser) {
        this.defaultValue = defaultValue;
        this.parser = parser;
    }

    public T getValue()
    {
        // depending on the parser, re-parsing every time this is called could get expensive!
        try
        {
            // here will be some logic to get String value from some db or any other source
            String input = "true";
            return parser.apply(input);
        } catch (Exception e) {
            return defaultValue;
        }
    }
}

You can now create a Node by doing this

Node<Boolean> node = new Node<>(s -> Boolean.parseBoolean(s))

You could also set the default value in the parser function, removing the need to store it in the node - it depends on your requirements.

  1. See 2.

EDIT I've using Java 8's Function interface and lambdas here, but you can just as easily do this in Java 1.0 by defining your own Function interface.

public interface Function<I, O> {
    O apply(I);
}

and then implement this in some way - concrete class, anonymous class, etc - as required for the parsing you need to do.

Node<Boolean> node = new Node<>(new Function<String, Boolean>() {
    public Boolean apply(String s) {
        return Boolean.parseBoolean(s);
    }
});

EDIT 2

In response to the comment about pre-defined types, you can take a few different approaches.

public class NodeFactory {
    private static final Function <String, Boolean> BOOLEAN_PARSER = s -> Boolean.parseBoolean(s);
    .// plus more for integers, double, etc, as required

    private NodeFactory() {
        // no-op
    } 

    public static Node<Boolean> booleanNode(boolean defaultValue){
        return new Node<Boolean>(defaultValue,
                                 BOOLEAN_PARSER);
    }

    // plus more for integer, double, etc, as required
}

or you can take the extension route

public class BooleanNode extends Node<Boolean> {
    public BooleanNode(boolean defaultValue) {
        super(defaultValue,
              s -> Boolean.parseBoolean(s)); // or use a static parser as in the factory example
    }
}

In any case, keeping Node non-abstract allows for a lot of flexibility for your users, but your use case may not require that.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to use Java Generics for returing T from String

From Dev

How to use generics of generics in java interfaces

From Dev

Returing string from main function in c++

From Dev

Returing string from main function in c++

From Dev

How to use generics in a java method

From Dev

How to use java generics with restTemplate

From Dev

Java generics - type mismatch from T to T

From Dev

How to use multiple bounds in java generics in this case

From Dev

How to specify in C# generics such T that is constructible from string? (generic type constraint)

From Dev

Returing method for string

From Dev

How to use parentheses for generics?

From Dev

How to use generics

From Dev

how to use generics in Scala

From Dev

How to use generics

From Dev

How to use generics in spring?

From Dev

how to use generics in Scala

From Dev

Java Comparing Generics with Comparable<? super T> from another class

From Dev

How to use injectLazy() delegate from Injekt library with generics?

From Dev

How to correctly use Java generics for an array implementation of an ADT

From Dev

java generics - how to implement a class that takes a HashSet<T>?

From Dev

How implement Java Generics

From Dev

How implement Java Generics

From Dev

Java Generics - use of extends keyword

From Dev

Is there any reason to use generics in Java?

From Dev

Java Generics - use of extends keyword

From Dev

Java Generics - How is a raw type different from a non generic type

From Dev

how to convert from a list of generics to list of objects in java 8?

From Dev

How can I call Kotlin methods with reified generics from Java?

From Dev

How do i differ primitive data types from generics in Java?

Related Related

HotTag

Archive