views:

110

answers:

5

I need to convert a Vector to a String (an vice versa) to be stored in a CHAR field in a database. What is the most efficient way to do this ?

+10  A: 

Let me get this straight... you want to store an array of strings in some format (say, CSV) into the DB in a single column, such that they can later be reconstituted into an array? This is a very bad idea. I know this because I have to suffer through working on a system every day that does exactly this. It's terrible to maintain, and if you ever want to query on this data, your code is going to be very complicated. Really, you should normalize your database such that you have a separate table for these strings (each row being one string) and replace your "string array" column in your current table with a foreign key to this new table.

rmeador
+1  A: 

You can try (from commons-lang):

ArrayUtils.toString(vector.toArray());
Bozho
+2  A: 

A Vector of Strings translates rather nicely to the relational database model. A Vector index is similar to a table id field and the String translates well to a CHAR field. It would be more natural to store the data in this format. When you need the Vector later, just reconstruct it instead of storing it in a single serialized field.

tehblanx
A: 

putting aside whether or what you are doing is a good idea, I would probably just make a stringstream and a for loop that writes into the stringstream. At the end, call str(). Not sure why it would need to be more complicated than some obvious solution like that.

frankc
A: 

The general strategy for an arbitrary vector would be to serialize the vector to bytes and then convert the bytes to a string without losing any data.

The the following example uses ByteArrayInput/OutputStream to hold the byte array in memory and encodes the result by packing two bytes per char. If your database transparently converts your strings to a different locale, you might need to use a different strategy for converting byte[] to String (e.g., base64). Alternatively, consider changing the database column to BLOB. Doing that would also avoid the need to hold the serialized data in memory, which might be important if your Vector is large.

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Vector;

public class a {
  public static void main(String[] args) throws Exception {
    Vector<Object> v = new Vector<Object>();
    v.add("hello");
    v.add(1);
    v.add(true);
    v.add(v);
    System.out.println(deserialize(serialize(v)));
  }

  private static String serialize(Object o) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(o);
    oos.close();

    byte[] bytes = baos.toByteArray();
    char[] chars = new char[(bytes.length + 1) / 2];

    for (int ci = 0, bi = 0; ci < chars.length; ci++) {
      chars[ci] = (char)(bytes[bi++] << 8);
      if (bi < bytes.length) {
        chars[ci] |= (char)(bytes[bi++] & 0xff);
      }
    }

    return new String(chars);
  }

  private static Object deserialize(String s)
      throws IOException, ClassNotFoundException {
    byte[] bytes = new byte[s.length() * 2];
    for (int ci = 0, bi = 0; ci < s.length(); ci++) {
      bytes[bi++] = (byte)(s.charAt(i) >> 8);
      bytes[bi++] = (byte)s.charAt(i);
    }

    return new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject();
  }
}
bkail