4

Suppose I need to parse space delimited lists of numbers where some lists contain integers and some lists contain doubles. What would be a good way to generalize the following functions to reduce repetition? I was thinking this might be a good use case for Generics?

public static ArrayList<Integer> stringToIntList(String str)
{
    String[] strs = str.split("\\s");
    ArrayList<Integer> output = new ArrayList<Integer>();
​
​
    for (String val : strs)
    {
        output.add(Integer.parseInt(val));
    }
​
    return output;
}
​
public static ArrayList<Double> stringToDoubleList(String str)
{
    String[] strs = str.split("\\s");
    ArrayList<Double> output = new ArrayList<Double>();
​
​
    for (String val : strs)
    {
        output.add(Double.parseDouble(val));
    }
​
    return output;
}

2 Answers 2

4

You can do this with generics if you have some sort of function (e.g. java.util.function.Function or com.google.common.base.Function) which takes a String and returns the desired type.

static <T> ArrayList<T> stringToList(
    String str, Function<? super String, ? extends T> fn) {
  String[] strs = str.split("\\s");
  ArrayList<T> output = new ArrayList<>();
  for (String val : strs)
  {
      output.add(fn.apply(val));
  }
  return output;
 }
Sign up to request clarification or add additional context in comments.

Comments

3

With Java 8, it can be quite concise:

static <T> List<T> convertToList(
        String string, Function<String, T> function) {
    return Pattern.compile("\\s").splitAsStream(string)
            .map(function).collect(Collectors.toList());
}

public static void main(String[] args) {
    String s = "3 4";
    System.out.println(convertToList(s,Double::parseDouble)); // [3.0, 4.0]
    System.out.println(convertToList(s,Integer::parseInt)); // [3, 4]
}

You can make the Pattern also a constant when it does not change.

6 Comments

When I try this, I get an error saying that the function is returning a List<java.lang.Object> rather than a List<T>. Do I need a cast there or something?
@evan058 how do you call it? You need to pass a function which returns T, but if T is Object you get List<Object>
I am using IntelliJ and the IDE is throwing that error. I have just defined the function and it says: Incompatible Types: Required: List<T>; Found List<java.lang.Object>
Ah, you need to do Collectors.<T>toList() rather than Collectors.toList()
Even still when I try to run ArrayList<Double> dubTimes = convertToList(times, Double::parseDouble) I get an error "Bad return type in method reference, cannot convert double to T" Andy Turner's answer works with this kind of method call
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.