2

I need to port code from blackberry to android and facing small problem: Example: the bb code is:

public class MyClass{
   private MyObject[] _myObject;

   public void addElement(MyObject o){
      if (_myObject == null){
        _myObject = new MyObject[0];
      }
      Arrays.add(_myObject, o);
   }
}

unfortunately android does not have Arrays.add() which is part of net.rim.device.api.util.Arrays (static void add(Object[] array, Object object))

Is there any replacement for android to dynamically extend and append in to simple array so I don't change the rest of my code.

I tried to write my own utility but it does not work:

public class Arrays {
  public static void add(Object[] array, Object object){
    ArrayList<Object> lst = new ArrayList<Object>();
    for (Object o : array){
      lst.add(o);
    }
    lst.add(object);
    array = lst.toArray();
  }
}

.. after I call

public void addElement(MyObject o){
      if (_myObject == null){
        _myObject = new MyObject[0];
      }
      Arrays.add(_myObject, o);
   }

the _myObject still contain 0 elements.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
kompotFX
  • 353
  • 2
  • 4
  • 13

2 Answers2

4

Yes, because the _myObject reference is passed by value. You'd need to use:

public static Object[] add(Object[] array, Object object){
  ArrayList<Object> lst = new ArrayList<Object>();
  for (Object o : array){
    lst.add(o);
  }
  lst.add(object);
  return lst.toArray();
}

...

_myObject = Arrays.add(_myObject, o);

However, it would be better to just use an ArrayList<E> to start with...

There are two important things to understand here:

Java always uses pass-by-value

The value which is passed is either a reference (a way of getting to an object, or null) or a primitive value. That means if you change the value of the parameter, that doesn't get seen by the caller. If you change the value of something within the object the parameter value refers to, that's a different matter:

void doSomething(Person person) {
  person.setName("New name"); // This will be visible to the caller
  person = new Person(); // This won't
}

Arrays are fixed-size in Java

You can't "add" a value to an array. Once you've created it, the size is fixed. If you want a variable-size collection (which is a very common requirement) you should use an implementation of List<E> such as ArrayList<E>.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • thanks for quick answer. Please, take a look to this spec: http://www.blackberry.com/developers/docs/3.7api/net/rim/device/api/util/Arrays.html There is void add(Object[] array, Object object); How do rim developers achieve that it works for them? I mean they just call add(object_array, new_element); and object_array extended with new element? – kompotFX Oct 07 '11 at 12:41
  • @kompotFX: They don't. It's entirely unclear what that badly-documented method does, but I can guarantee you that if you print out `array.length`, then call `add(array, "hello")`, then print `array.length` again, it'll have the same value. It's possible that it looks for an element in the array which has a null value, and set the value of that element to the one that was passed in. That's not the same thing as *adding* though. – Jon Skeet Oct 07 '11 at 12:42
  • it is very strange, because actually the sample of code I need to port works on blackberry. – kompotFX Oct 07 '11 at 12:44
  • @kompotFX: Well the code you've given at the top would *always* leave `_myObject` as a length-0 array. That's assuming RIM hasn't broken the way that Java works, of course, but I doubt that they have. If you can show a short but complete program showing RIM's code working, that would be useful. – Jon Skeet Oct 07 '11 at 12:46
  • so, you want to say that RIM developers are wrong with this: ? – kompotFX Oct 07 '11 at 12:54
  • @kompotFX: Almost certainly, unless their "version" of Java is fundamentally different to everyone else's. Again, some sample code showing how that code "works" would be useful. – Jon Skeet Oct 07 '11 at 12:57
  • unfortunately it is a part of huge project and I am sure 100% that this application and currently this method works on blackberry device. – kompotFX Oct 07 '11 at 13:01
  • @kompotFX: Just because you've got something working as part of a big project doesn't mean you'd have to post the project. Just a short but complete bit of code which shows it working. Something which creates an array of length 5 (say), passes a reference to that array to the `Arrays.add` method, and then prints out the length again afterwards... – Jon Skeet Oct 07 '11 at 13:02
  • check real example here: http://docs.blackberry.com/en/developers/deliverables/11942/CS_record_video_without_using_the_camera_app_734825_11.jsp Look for method private String[] getEncodings() – kompotFX Oct 07 '11 at 13:23
  • @kompotFX: Right, that seems unambiguous. Under normal Java, there is **no way** that can work. So either their code really is broken, or their implementation of Java is completely wacky. – Jon Skeet Oct 07 '11 at 13:25
  • @kompotFX: Just looking at [this](http://supportforums.blackberry.com/t5/Java-Development/Where-is-Arrays-add/td-p/395462) it looks like it's gone in later versions of the API... so maybe they've stopped the craziness over time. – Jon Skeet Oct 07 '11 at 13:26
2

Here's the code of ObjectArrays.concat(object, array):

public static <T> T[] concat(@Nullable T element, T[] array) {
    T[] result = newArray(array, array.length + 1);
    result[0] = element;
    System.arraycopy(array, 0, result, 1, array.length);
    return result;
  }

The apache-commons code is a bit longer.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140