views:

242

answers:

5

Assume a class (for instance URI) that is convertable to and from a String using the constructor and toString() method.

I have an ArrayList<URI> and I want to copy it to an ArrayList<String>, or the other way around.

Is there a utility function in the Java standard library that will do it? Something like:

java.util.collections.copy(urlArray,stringArray);

I know there are utility libraries that provide that function, but I don't want to add an unnecessary library.

I also know how to write such a function, but it's annoying to read code and find that someone has written functions that already exist in the standard library.

+3  A: 

No, there is no standard JDK shortcut to do this.

Yishai
There was going to be a parallel array transform function in the fork-join framework of JDK7, but all that stuff got removed due to lack of agreement (IIRC).
Tom Hawtin - tackline
... and that's one of the problems with consensus-based standard making :-(
Stephen C
A: 

Since two types of collections may not be compatible, there is no built-in method for converting one typed collection to another typed collection.

rob
+1  A: 

Have a look at commons-collections:

http://commons.apache.org/collections/

I believe that CollectionUtils has a transform method.

Eric
Presumably the google collection library has something similar.
Tom Hawtin - tackline
sorry, just saw that you didn't want to add additional libraries.
Eric
+2  A: 

I know you don't want to add additional libraries, but for anyone who finds this from a search engine, in google-collections you might use:

List<String> strings = Lists.transform(uris, Functions.toStringFunction());

one way, and

List<String> uris = Lists.transform(strings, new Function<String, URI>() {
  public URI apply(String from) {
     try {
       return new URI(from);
     } catch (URISyntaxException e) {
       // whatever you need to do here
     }
  }
});

the other.

Cowan
A: 

Try:

public ArrayList<String> convert(ArrayList<URI> source) {
    ArrayList<String> dest=new ArrayList<String>();

    for(URI uri : source)
        dest.add(source.toString());

   return dest;
}

Seriously, would a built-in API offer a lot to that?

Also, not very OO. the URI array should probably be wrapped in a class. The class might have a .asStrings() method.

Furthermore you'll probably find that you don't even need (or even want) the String collection version if you write your URI class correctly. You may just want a getAsString(int index) method, or a getStringIterator() method on your URI class, then you can pass your URI class in to whatever method you were going to pass your string collection to.

Bill K
Actually this is VERY OO. You do it all the time in dynamically-typed languages like JavaScript and Python. Static typing is not a requirement of OO.I may end up writing a convert() funtion like yours but it will take generics. "String" is a special case among built-in types: every Object has a toString() method but there is no requirement that "MyClass newObj = new MyClass(oldObj.toString());" yield an object such that newObj.equals(oldObj). In Python the "__repr__" method does that, and in JavaScript you can convert anything to JSON and back.
Mark Lutton
Actually the non-oo issue isn't that it's not a type, it's that what I wrote above isn't a method, it's a function. At a basic level, if you are writing functions instead of methods you are either patching something you can't make OO (because of pre-existing code) or you are doing it wrong.
Bill K
(By the way, I didn't mean for that to sound so absolute. There are exceptions--like reusable utility functions such as this--but more often than not even the exceptions should be inside business classes at some point). Anyway, the point is that the object API that you provide to the rest of your system, at any point, should be based on business logic classes and not utility functions and collections because those cannot be made into a decent API no matter how hard you try.
Bill K