Làm thế nào để thêm các phần tử mới vào một mảng?


291

Tôi có đoạn mã sau:

String[] where;
where.append(ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1");
where.append(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1");

Hai phụ lục này không được biên dịch. Làm thế nào mà hoạt động chính xác?

Câu trả lời:


395

Kích thước của một mảng không thể được sửa đổi. Nếu bạn muốn một mảng lớn hơn, bạn phải khởi tạo một mảng mới.

Một giải pháp tốt hơn sẽ là sử dụng một ArrayListthứ có thể phát triển khi bạn cần. Phương thức ArrayList.toArray( T[] a )cung cấp cho bạn trở lại mảng của bạn nếu bạn cần nó trong mẫu này.

List<String> where = new ArrayList<String>();
where.add( ContactsContract.Contacts.HAS_PHONE_NUMBER+"=1" );
where.add( ContactsContract.Contacts.IN_VISIBLE_GROUP+"=1" );

Nếu bạn cần chuyển đổi nó thành một mảng đơn giản ...

String[] simpleArray = new String[ where.size() ];
where.toArray( simpleArray );

Nhưng hầu hết mọi thứ bạn làm với một mảng bạn cũng có thể làm với ArrayList này:

// iterate over the array
for( String oneItem : where ) {
    ...
}

// get specific items
where.get( 1 );

9
Điểm nào trong việc sử dụng Array nếu bạn có thể làm tương tự với ArrayList?
Skoua

@ tangens. Tôi mới dùng Android nhưng câu trả lời của bạn đã giúp tôi. Trước khi tìm câu trả lời tôi đã lãng phí nhiều giờ
scott

1
Mảng @Skoua hiệu quả hơn. Xác định trước kích thước đối tượng cho phép trình biên dịch tối ưu hóa bộ nhớ. Đối với một số ứng dụng, nó quan trọng. Một ứng dụng nhỏ chạy trên máy tính hiện đại có thể có thể thoát khỏi rất nhiều Danh sách trước khi bộ nhớ trở thành vấn đề.
DraxDomax

102

Sử dụng một List<String>, chẳng hạn như một ArrayList<String>. Nó có thể phát triển linh hoạt, không giống như các mảng (xem: Phiên bản Java 2 hiệu quả, Mục 25: Thích danh sách cho các mảng ).

import java.util.*;
//....

List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
System.out.println(list); // prints "[1, 2, 3]"

Nếu bạn khăng khăng sử dụng mảng, bạn có thể sử dụng java.util.Arrays.copyOfđể phân bổ một mảng lớn hơn để chứa phần tử bổ sung. Đây thực sự không phải là giải pháp tốt nhất.

static <T> T[] append(T[] arr, T element) {
    final int N = arr.length;
    arr = Arrays.copyOf(arr, N + 1);
    arr[N] = element;
    return arr;
}

String[] arr = { "1", "2", "3" };
System.out.println(Arrays.toString(arr)); // prints "[1, 2, 3]"
arr = append(arr, "4");
System.out.println(Arrays.toString(arr)); // prints "[1, 2, 3, 4]"

Đây là O(N)mỗi append. ArrayListmặt khác, đã O(1)khấu hao chi phí cho mỗi hoạt động.

Xem thêm


Bạn có thể tăng gấp đôi kích thước của mảng mỗi khi dung lượng không đủ. Bằng cách đó, phần bổ sung sẽ được khấu hao O (1). Có lẽ những gì ArrayListlàm trong nội bộ.
Siyuan Ren

32

Commons Lang có

T[] t = ArrayUtils.add( initialArray, newitem );

nó trả về một mảng mới, nhưng nếu bạn thực sự làm việc với mảng vì một số lý do, đây có thể là cách lý tưởng để làm điều này.


23

Có một tùy chọn khác mà tôi chưa thấy ở đây và không liên quan đến các Đối tượng hoặc Bộ sưu tập "phức tạp".

String[] array1 = new String[]{"one", "two"};
String[] array2 = new String[]{"three"};
String[] array = new String[array1.length + array2.length];
System.arraycopy(array1, 0, array, 0, array1.length);
System.arraycopy(array2, 0, array, array1.length, array2.length);

14

Không có phương pháp append()trên mảng. Thay vào đó, như đã đề xuất, một đối tượng List có thể phục vụ nhu cầu chèn động các phần tử, vd.

List<String> where = new ArrayList<String>();
where.add(ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1");
where.add(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1");

Hoặc nếu bạn thực sự muốn sử dụng một mảng:

String[] where = new String[]{
    ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1",
    ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"
};

nhưng sau đó đây là một kích thước cố định và không có yếu tố nào có thể được thêm vào.


Vì vậy, một truy vấn được tham số hóa có chấp nhận ArrayList là selectArss không?
Skynet

7

Như tangens đã nói, kích thước của một mảng là cố định. Nhưng bạn phải khởi tạo nó trước, nếu không nó sẽ chỉ là một tham chiếu null.

String[] where = new String[10];

Mảng này chỉ có thể chứa 10 phần tử. Vì vậy, bạn có thể nối một giá trị chỉ 10 lần. Trong mã của bạn, bạn đang truy cập một tài liệu tham khảo null. Đó là lý do tại sao nó không hoạt động. Để có một bộ sưu tập phát triển linh hoạt, hãy sử dụng ArrayList.


7
String[] source = new String[] { "a", "b", "c", "d" };
String[] destination = new String[source.length + 2];
destination[0] = "/bin/sh";
destination[1] = "-c";
System.arraycopy(source, 0, destination, 2, source.length);

for (String parts : destination) {
  System.out.println(parts);
}

6

Tôi đã tạo mã này! Nó hoạt động như một say mê!

public String[] AddToStringArray(String[] oldArray, String newString)
{
    String[] newArray = Arrays.copyOf(oldArray, oldArray.length+1);
    newArray[oldArray.length] = newString;
    return newArray;
}

Tôi hy vọng bạn thích nó!!


5

Bạn cần sử dụng Danh sách Bộ sưu tập. Bạn không thể định kích thước lại một mảng.


4

Nếu bạn muốn lưu trữ dữ liệu của mình trong mảng đơn giản như thế này

String[] where = new String[10];

và bạn muốn thêm một số phần tử vào nó như số, vui lòng cho chúng tôi StringBuilder hiệu quả hơn nhiều so với chuỗi nối.

StringBuilder phoneNumber = new StringBuilder();
phoneNumber.append("1");
phoneNumber.append("2");
where[0] = phoneNumber.toString();

Đây là phương pháp tốt hơn nhiều để xây dựng chuỗi của bạn và lưu trữ nó vào mảng 'where' của bạn.


4

Thêm các mục mới vào mảng Chuỗi.

String[] myArray = new String[] {"x", "y"};

// Convert array to list
List<String> listFromArray = Arrays.asList(myArray);

// Create new list, because, List to Array always returns a fixed-size list backed by the specified array.
List<String> tempList = new ArrayList<String>(listFromArray);
tempList.add("z");

//Convert list back to array
String[] tempArray = new String[tempList.size()];
myArray = tempList.toArray(tempArray);

1
À, tôi hiểu rồi, bạn đã sử dụng <code>thẻ và điều này có vấn đề với các loại chung. Vui lòng cố gắng tránh thẻ này, vì ... nó có vấn đề và thụt mã của bạn với 4 khoảng trắng để có được định dạng phù hợp. Tôi đã làm điều đó cho câu hỏi của bạn :).
Tom

4

Có nhiều cách để thêm một phần tử vào một mảng. Bạn có thể sử dụng một temp Listđể quản lý phần tử và sau đó chuyển đổi nó trở lại Arrayhoặc bạn có thể sử dụng java.util.Arrays.copyOfvà kết hợp nó với generic để có kết quả tốt hơn.

Ví dụ này sẽ cho bạn thấy làm thế nào:

public static <T> T[] append2Array(T[] elements, T element)
{
    T[] newArray = Arrays.copyOf(elements, elements.length + 1);
    newArray[elements.length] = element;

    return newArray;
}

Để sử dụng phương pháp này, bạn chỉ cần gọi nó như thế này:

String[] numbers = new String[]{"one", "two", "three"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(numbers, "four");
System.out.println(Arrays.toString(numbers));

Nếu bạn muốn hợp nhất hai mảng, bạn có thể sửa đổi phương thức trước đó như sau:

public static <T> T[] append2Array(T[] elements, T[] newElements)
{
    T[] newArray = Arrays.copyOf(elements, elements.length + newElements.length);
    System.arraycopy(newElements, 0, newArray, elements.length, newElements.length);

    return newArray;
}

Bây giờ bạn có thể gọi phương thức như thế này:

String[] numbers = new String[]{"one", "two", "three"};
String[] moreNumbers = new String[]{"four", "five", "six"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(numbers, moreNumbers);
System.out.println(Arrays.toString(numbers));

Như tôi đã đề cập, bạn cũng có thể sử dụng Listcác đối tượng. Tuy nhiên, nó sẽ yêu cầu một chút hack để sử dụng nó an toàn như thế này:

public static <T> T[] append2Array(Class<T[]> clazz, List<T> elements, T element)
{
    elements.add(element);
    return clazz.cast(elements.toArray());
}

Bây giờ bạn có thể gọi phương thức như thế này:

String[] numbers = new String[]{"one", "two", "three"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(String[].class, Arrays.asList(numbers), "four");
System.out.println(Arrays.toString(numbers));

newArray[elements.length] = element;ý bạn là newArray[elements.length - 1] = element;sao
David Riccitelli

3

Tôi không có kinh nghiệm về Java nhưng tôi luôn được thông báo rằng các mảng là các cấu trúc tĩnh có kích thước được xác định trước. Bạn phải sử dụng ArrayList hoặc Vector hoặc bất kỳ cấu trúc động nào khác.


2

bạn có thể tạo một Collection.addAll()danh sách mảng và sử dụng để chuyển đổi chuỗi chuỗi thành danh sách mảng của bạn


2

Bạn chỉ có thể làm điều này:

System.arraycopy(initialArray, 0, newArray, 0, initialArray.length);

2

Nếu một người thực sự muốn thay đổi kích thước một mảng, bạn có thể làm một cái gì đó như thế này:

String[] arr = {"a", "b", "c"};
System.out.println(Arrays.toString(arr)); 
// Output is: [a, b, c]

arr = Arrays.copyOf(arr, 10); // new size will be 10 elements
arr[3] = "d";
arr[4] = "e";
arr[5] = "f";

System.out.println(Arrays.toString(arr));
// Output is: [a, b, c, d, e, f, null, null, null, null]

1

Kích thước của mảng không thể được sửa đổi. Nếu bạn phải sử dụng một mảng, bạn có thể sử dụng:

System.arraycopy(src, srcpos, dest, destpos, length); 

0

Cũng có thể phân bổ trước kích thước bộ nhớ đủ lớn. Đây là một cách thực hiện ngăn xếp đơn giản: chương trình được cho là xuất 3 và 5.

class Stk {
    static public final int STKSIZ = 256;
    public int[] info = new int[STKSIZ];
    public int sp = 0; // stack pointer
    public void push(int value) {
        info[sp++] = value;
    }
}
class App {
    public static void main(String[] args) {
        Stk stk = new Stk();
        stk.push(3);
        stk.push(5);
        System.out.println(stk.info[0]);
        System.out.println(stk.info[1]);
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.