36

Is it possible to add a string to beginning of String array without iterating the entire array.

Anand B
  • 2,997
  • 11
  • 34
  • 55
  • Using a different data structure that fits your needs (e.g. `ArrayList`) would be better. – Sulthan Jan 10 '13 at 13:34
  • 1
    Use ArrayUtils.add(T[] array, int index,T element)(https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#add-T:A-int-T-) – Tadeu Jr. Dec 23 '16 at 13:14

10 Answers10

21

The only way to do this is to maintain a ring buffer. i.e. you have a counter which remembers where the start is and you move that instead of moving all the entries in the array. This only works because you re-define what the "start" means.

See the source for ArrayDeque which has three fields

   86       /**
   87        * The array in which the elements of the deque are stored.
   88        * The capacity of the deque is the length of this array, which is
   89        * always a power of two. The array is never allowed to become
   90        * full, except transiently within an addX method where it is
   91        * resized (see doubleCapacity) immediately upon becoming full,
   92        * thus avoiding head and tail wrapping around to equal each
   93        * other.  We also guarantee that all array cells not holding
   94        * deque elements are always null.
   95        */
   96       private transient E[] elements;
   97   
   98       /**
   99        * The index of the element at the head of the deque (which is the
  100        * element that would be removed by remove() or pop()); or an
  101        * arbitrary number equal to tail if the deque is empty.
  102        */
  103       private transient int head;
  104   
  105       /**
  106        * The index at which the next element would be added to the tail
  107        * of the deque (via addLast(E), add(E), or push(E)).
  108        */
  109       private transient int tail;

So adding to the start works like this

  224       public void addFirst(E e) {
  225           if (e == null)
  226               throw new NullPointerException();
  227           elements[head = (head - 1) & (elements.length - 1)] = e;
  228           if (head == tail)
  229               doubleCapacity();
  230       }


  312       /**
  313        * @throws NoSuchElementException {@inheritDoc}
  314        */
  315       public E getFirst() {
  316           E x = elements[head];
  317           if (x == null)
  318               throw new NoSuchElementException();
  319           return x;
  320       }

Note: it moves the head rather than shifting all the elements down the array.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
19

try

    String[] a = {"1", "2"};
    String[] a2 = new String[a.length + 1];
    a2[0] = "0";
    System.arraycopy(a, 0, a2, 1, a.length);
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
15

If you're already using Guava you can use ObjectArrays::concat to do this:

String[] args = ...;
ObjectArrays.concat("prepended", args);
Jon Tirsen
  • 4,750
  • 4
  • 29
  • 27
7

This is corrected version of solution proposed by @matteosilv:

String[] myArray= {"hi","hi2"};
List<String> list = new LinkedList<String>(Arrays.asList(myArray));
list.add(0, "h3");
myArray = list.toArray(new String[list.size()]);
Stéphane GRILLON
  • 11,140
  • 10
  • 85
  • 154
Daniil Shevelev
  • 11,739
  • 12
  • 50
  • 73
4

You cant...You have to move all the strings coming after it forward to accommodate the new string. If you are directly adding it to 0th index, you will lose the previous element there

Renjith
  • 3,274
  • 19
  • 39
3
String[] myArray= {"hi","hi2"};
List<String> temp = new ArrayList<String>(Arrays.asList(prova));
temp.add(0, "h3");
myArray = temp.toArray(new String[temp.size()]);
matteosilv
  • 585
  • 7
  • 13
  • Actually your solution does not work asis. Here is why: http://stackoverflow.com/a/2965808/1515058 This will work: String[] myArray= {"hi","hi2"}; List list = new LinkedList(Arrays.asList(myArray)); list.add(0, "h3"); myArray = list.toArray(new String[temp.size()]); – Daniil Shevelev Jan 09 '14 at 20:06
2

You can use streams

  private Object[] prepend(String prefix, String[] row) {
        Stream<String> stream = Stream.concat(Arrays.asList(prefix).stream(), Arrays.asList(row).stream());
        return stream.toArray();
    }

calling

prepend("one",new String[]{"two","three","four"})

result

$1 ==> Object[4] { "one", "two", "three", "four" }

Ion Mihov
  • 21
  • 1
1

To do that, you should use List.

And if you want to particularly use the arrays internal, go for an ArrayList

Jerome
  • 2,104
  • 1
  • 17
  • 31
  • You cannot do a getFirst(...), getLast(...), addFirst(...), addLast(...), removeFirst(...), or removeLast(...) with an ArrayList. It doesn’t provide extra methods for easy operation on the list’s ends, as LinkedList does – sr01853 Jan 10 '13 at 11:06
  • 2
    @Sibi I think you'll find you can with add(int index, E e) ... see here http://docs.oracle.com/javase/6/docs/api/java/util/List.html#add%28int,%20E%29 – xagyg Jan 10 '13 at 11:13
1

Best I can manage ...

public static void main(String[] args) {
        String[] s = new String[] { "a", "b", "c" };
        System.out.println(Arrays.toString(prepend(s,"d")));
}

public static String[] prepend(String[] a, String el) {
        String[] c = new String[a.length+1];
        c[0] = el;
        System.arraycopy(a, 0, c, 1, a.length);
        return c;
}
xagyg
  • 9,562
  • 2
  • 32
  • 29
1

You can do some thing like below

public class Test {

public static String[] addFirst(String s[], String e) {
    String[] temp = new String[s.length + 1];
    temp[0] = e;
    System.arraycopy(s, 0, temp, 1, s.length);
    return temp;
}

public static void main(String[] args) {
    String[] s = { "b", "c" };
    s = addFirst(s, "a");
    System.out.println(Arrays.toString(s));
}
}
Krushna
  • 5,059
  • 5
  • 32
  • 49