2009-04-16 31 views
105

Đây có thể là một loại câu hỏi dễ dàng, nặng nề, nhưng lần thử đầu tiên của tôi hoàn toàn không thành công. Tôi muốn lấy một loạt các thời kỳ nguyên thủy và biến nó thành một danh sách, mà tôi đã cố gắng làm như sau:Chuyển đổi một loạt các đoạn mã nguyên thủy thành Danh sách các Longs

long[] input = someAPI.getSomeLongs(); 
List<Long> inputAsList = Arrays.asList(input); //Total failure to even compile! 

Cách nào để làm điều này?

+5

Tôi nghĩ chúng tôi đã có cùng một câu hỏi cho ints, không có chúng? –

+1

@Tom, có: http://stackoverflow.com/questions/1467913/arrays-aslist-not-working-as-it-should – finnw

Trả lời

94

tôi thấy nó thuận tiện để làm bằng commons apache lang ArrayUtils (JavaDoc)

long[] input = someAPI.getSomeLongs(); 
Long[] inputBoxed = ArrayUtils.toObject(input); 
List<Long> inputAsList = Arrays.asList(inputBoxed); 

nó cũng có API ngược

long[] backToPrimitive = ArrayUtils.toPrimitive(objectArray); 

EDIT: cập nhật để cung cấp một chuyển đổi hoàn toàn đến một danh sách theo đề xuất của các nhận xét và các bản sửa lỗi khác.

+3

Xem xét rằng điều này tạo ra một _array_ của Longs, _not một List_, nó không trả lời câu hỏi của OP và được downvote của tôi. Làm thế nào heck này đã nhận được 56 upvotes và thèm muốn "kiểm tra" ??? – user949300

+6

Bởi vì mọi người có thể dễ dàng thực hiện 'Arrays.asList (ArrayUtils.toObject (input))'. –

+0

Tôi đồng ý với @ user949300. Điều này không trả lời câu hỏi. – ovaherenow

16

Một chút tiết hơn, nhưng công trình này:

List<Long> list = new ArrayList<Long>(); 
    for (long value : input) { 
     list.add(value); 
    } 

Trong ví dụ của bạn có vẻ như Arrays.asList() được giải thích các đầu vào như danh sách [] mảng dài thay vì một danh sách các Longs. Một chút ngạc nhiên, chắc chắn. Tự động tạo không hoạt động theo cách bạn muốn trong trường hợp này.

7

Không, không có chuyển đổi tự động từ mảng kiểu nguyên thủy thành mảng của các loại tham chiếu được đóng hộp của chúng. Bạn chỉ có thể làm

long[] input = someAPI.getSomeLongs(); 
List<Long> lst = new ArrayList<Long>(); 

for(long l : input) lst.add(l); 
2

Nếu bạn muốn ngữ nghĩa tương tự như Arrays.asList sau đó bạn sẽ cần phải viết (hoặc sử dụng của người khác) thực hiện khách hàng của List (có thể là thông qua AbstractList. Nó cần phải có nhiều việc thực hiện tương tự như Arrays.asList, . chỉ hộp và Unbox giá trị

29

hallidavejpalecek có ý tưởng đúng — iterating trên một mảng — nhưng họ không tận dụng lợi thế của một tính năng được cung cấp bởi ArrayList: kể từ kích thước của danh sách được biết đến trong trường hợp này, bạn nên chỉ định nó khi bạn tạo ArrayList.

List<Long> list = new ArrayList<Long>(input.length); 
for (long n : input) 
    list.add(n); 

Bằng cách này, không có mảng không cần thiết được tạo ra chỉ để bị loại bỏ bởi các ArrayList vì họ bật ra được quá ngắn, và không có "khe" trống rỗng đang bị lãng phí vì ArrayList đánh giá quá cao các yêu cầu không gian của nó. Tất nhiên, nếu bạn tiếp tục thêm các phần tử vào danh sách, một mảng sao lưu mới sẽ là cần thiết.

+0

Tôi có xu hướng bỏ qua đặc tả độ dài trừ khi mã được chứng minh là một phần của hiệu suất điểm nóng hoặc mảng được mong đợi là cực kỳ lớn. Tôi nghĩ rằng để lại chiều dài làm cho mã hơi dễ đọc hơn. – hallidave

2

Bạn có thể sử dụng transmorph:

Transmorph transmorph = new Transmorph(new DefaultConverters()); 
List<Long> = transmorph.convert(new long[] {1,2,3,4}, new TypeReference<List<Long>>() {}); 

Nó cũng hoạt động nếu nguồn là một mảng của ints ví dụ.

4

Tôi đang viết một thư viện nhỏ cho những vấn đề này:

long[] input = someAPI.getSomeLongs(); 
List<Long> = $(input).toList(); 

Trong trường hợp bạn quan tâm kiểm tra xem nó here.

+0

thư viện đẹp! lúc đầu, tôi đã không chắc chắn nó đã được Java ... Tôi thích phong cách JQuery –

37
import java.util.Arrays; 
import org.apache.commons.lang.ArrayUtils; 

List<Long> longs = Arrays.asList(ArrayUtils.toObject(new long[] {1,2,3,4})); 
+2

Một lời giải thích về những gì điều này làm và cho dù đây là một thư viện của bên thứ ba sẽ hữu ích. –

2

Tôi biết câu hỏi này là đủ tuổi, nhưng ... bạn cũng có thể viết phương pháp chuyển đổi của riêng bạn:

@SuppressWarnings("unchecked") 
public static <T> List<T> toList(Object... items) { 

    List<T> list = new ArrayList<T>(); 

    if (items.length == 1 && items[0].getClass().isArray()) { 
     int length = Array.getLength(items[0]); 
     for (int i = 0; i < length; i++) { 
      Object element = Array.get(items[0], i); 
      T item = (T)element; 
      list.add(item); 
     } 
    } else { 
     for (Object i : items) { 
      T item = (T)i; 
      list.add(item); 
     } 
    } 

    return list; 
} 

Sau khi bạn đưa nó sử dụng nhập khẩu tĩnh, tập quán có thể là:

long[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
    List<Long> list = toList(array); 

hoặc

List<Long> list = toList(1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l, 9l); 
+0

liên quan đến: 'catch (ArrayIndexOutOfBoundsException ex) {/ * Hoàn thành việc nhận các phần tử mảng * /}', bạn là một người khủng khiếp. –

+0

Hey, người đàn ông, cảm ơn vì điều đó! Nhận xét mỉa mai của bạn làm cho tôi tìm thấy một giải pháp tốt hơn - nhận được chiều dài của mảng thông qua Array.getLength(). –

+0

Tuyệt vời! Tôi rất vui vì thái độ hèn nhát của tôi đã dẫn đến sự tiến bộ thay vì chỉ những cảm xúc xấu chung chung xung quanh :) Thực sự, không nên sử dụng ngoại lệ ngoại trừ trong những điều kiện rất bất thường. Chúng đắt tiền đáng kinh ngạc để tạo ra.Phiên bản mới này nhiều, MUCH nhanh hơn. –

3

Kết hợp Pavel và câu trả lời của Tom chúng tôi có được điều này

@SuppressWarnings("unchecked") 
    public static <T> List<T> asList(final Object array) { 
     if (!array.getClass().isArray()) 
      throw new IllegalArgumentException("Not an array"); 
     return new AbstractList<T>() { 
      @Override 
      public T get(int index) { 
       return (T) Array.get(array, index); 
      } 

      @Override 
      public int size() { 
       return Array.getLength(array); 
      } 
     }; 
    } 
61

Kể từ Java 8 bây giờ bạn có thể sử dụng con suối cho rằng:

long[] arr = {1,2,3,4}; 
List<Long> list = Arrays.stream(arr).boxed().collect(Collectors.toList()); 
+2

Đẹp nhất! Thật không may, và hơi bí ẩn, hàm 'stream' chỉ được định nghĩa cho' int [] ',' long [] 'và' double [] '. – Norswap

+1

Hoặc, bạn có thể sử dụng 'LongStream.of (arr) .boxed() ...'. – aioobe

+1

'Arrays.stream (arr) .boxed(). Collect (Collectors.toList()); 'Thật không may điều này chỉ có thể trả về' Danh sách ' –

15

Như một khả năng khác, the Guava library cung cấp này như Longs.asList(), với các lớp tiện ích tương tự cho các loại nguyên thủy khác.

import com.google.common.primitives.Longs; 

long[] input = someAPI.getSomeLongs(); 
List<Long> output = Longs.asList(input); 
3

way Một với Java 8.

final long[] a = new long[]{1L, 2L}; 
final List<Long> l = Arrays.stream(a).boxed().collect(Collectors.toList()); 
+1

Khi trả lại danh sách (không gán nó), tôi thấy mình phải làm: 'Arrays.stream (a) .boxed(). Collect (Người sưu tập. toList());' – Jon

+0

Điều này giống hệt với [câu trả lời hiện có này ] (https://stackoverflow.com/a/23117638). – Pang

+0

@Pang Thật vậy ... –

4

Một cách khác với Java 8.

long[] input = someAPI.getSomeLongs(); 
LongStream.of(input).boxed().collect(Collectors.toList())); 
Các vấn đề liên quan