2013-07-24 38 views
8

Tôi muốn biết nếu có thể giải nén một mảng đối tượng vào đối tượng riêng biệt trên cuộc gọi phương thức chấp nhận vargs. Câu hỏi này tương tự như this one.Làm thế nào để giải nén một mảng vào các đối số khác nhau về phương thức gọi

Tôi có một mã như:

public class Test { 
    public static Object doWork(Object... objects){ 
     System.out.println(objects.length); 
     return objects; 
    } 

    public static void main(String[] args){ 
     Object res = doWork("one", "two"); 
     res = doWork("three", res); 
    } 
} 

Tôi muốn giải nén các đối tượng res trong cuộc gọi thứ hai vì vậy nó sẽ nhận được một mảng đối tượng với chiều dài 3 thay vì chiều dài 2 như hiện nay (trong đó vị trí thứ hai là một mảng đối tượng có chiều dài 2, sau đó có cả ba đối số).

Thậm chí có thể trong Java không?


chi tiết thêm:

Bằng cách

Object res = doWork("one", "two"); 
res = doWork("three", res); 

cuộc gọi thứ hai được gọi là:

doWork(Object[ "three", Object[ "one", "two" ] ]) 

nơi mà tôi muốn:

doWork(Object[ "one", "two", "three" ]) 

Tôi biết điều này có thể đạt được bằng cách thực hiện:

public static void main(String[] args){ 
res = doWork("one", "two"); 
    List<Object> los = Arrays.asList(res); 
    los = new ArrayList<>(los);  // Can't modify an underlying array 
    los.add("three"); 
    res = doWork(los.toArray()); 
} 

Nhưng tôi đang tìm kiếm một cái gì đó giống như unpack Lua xây dựng trong chức năng hoặc cách Python được mô tả trong SO câu hỏi đề cập trước đây.


Cả hai câu trả lời được đưa ra bởi @chancea và @ Cyrille-ka đều tốt và cũng có thể giải quyết được sự cố. Một trong những sự kiện có thể là một ý tưởng tốt để đưa vào tài khoản là nếu chữ ký của phương pháp có thể được sửa đổi. @ cyrille-ka trả lời tôn trọng chữ ký của hàm, trong khi @chancea thì không. Tuy nhiên, tôi nghĩ rằng trong hầu hết các trường hợp, người ta chỉ có thể viết hàm bao hàm asimple cho một hàm khác, do đó không phải là vấn đề. Mặt khác cách @ chancea có thể dễ sử dụng hơn trong khi lập trình (không có lỗi nào có thể quên khi gọi hàm giải nén).

+0

Thay vì giải nén bạn có thể thử để làm cho một phương pháp quá tải mà phải mất một mảng và sau đó các mảng khác nhau 'DoWork (Object [] objects1, Object ... objects2) 'và sau đó kết hợp chúng trong phương pháp .. .just một ý tưởng Tôi không thực sự biết nếu điều đó sẽ làm việc cho vấn đề của bạn. Bạn sẽ phải gọi nó như 'doWork (res," ba ")' thay vì 'doWork (" ba ", res)' – chancea

+0

có thể trùng lặp của [Làm thế nào để nối hai mảng trong Java?] (Http: // stackoverflow. com/questions/80476/how-to-concatenate-two-array-in-java) –

+0

@JonathanDrapeau không có điều này là khác biệt và sâu hơn so với chỉ ghép nối với mảng – chancea

Trả lời

2

Vâng, không có cú pháp đường à la Python hoặc Lua cho rằng trong Java, nhưng bạn có thể tạo unpack phương pháp riêng của bạn:

@SafeVarargs 
public static <E> Object[] unpack(E... objects) { 
    List<Object> list = new ArrayList<Object>(); 
    for (Object object : objects) { 
     if (object instanceof Object[]) { 
      list.addAll(Arrays.asList((Object[]) object)); 
     } 
     else{ 
      list.add(object); 
     } 
    } 

    return list.toArray(new Object[list.size()]); 
} 

Điều này sẽ trả về một mảng chứa tất cả các yếu tố đầu vào, giải nén.

Sau đó, bạn có thể gọi nó trong phương pháp main của bạn:

res = doWork(unpack("three", res)); 

Lý do tôi thực hiện phương pháp này chung chung là bạn có thể gọi nó với, ví dụ, một mảng String[], mà không tạo ra một cảnh báo. Vì lý do nào đó, trình biên dịch Java cho rằng phương pháp này có khả năng "gây ô nhiễm đống", nhưng không phải vậy, đó là lý do tại sao tôi thêm chú thích @SafeVarargs.

0

Thay vào đó, hãy thử trở lại dưới dạng mảng Object. Sau đó, ghép nối "three" ở cuối mảng được trả về.

1

Điều này không thực hiện giải pháp Unpack, thay vào đó, hãy giải quyết nó bằng cách thực hiện overload method như tôi đã nói trong nhận xét của mình. Tôi không biết nếu điều này ở tất cả những gì bạn muốn, nhưng tôi đã nhận nó để làm việc và tôi cảm thấy như tôi sẽ đăng bài này để tham khảo.

public class Test { 
    public static Object doWork(Object... objects){ 
     System.out.println(objects.length); 
     return objects; 
    } 

    // this is the method that will concatenate the arrays for you 
    public static Object doWork(Object[] objects1, Object... objects2){ 
     System.out.println(objects1.length + "+" + objects2.length); 
     Object[] retval = new Object[objects1.length+objects2.length]; 
     System.arraycopy(objects1, 0, retval, 0, objects1.length); 
     System.arraycopy(objects2, 0, retval, objects1.length, objects2.length); 
     return retval; 
    } 

    public static void main(String[] args){ 
     Object res = doWork("one", "two"); 
     res = doWork((Object[])res, "three"); 
     Object[] res2 = (Object[])res; // = {one, two, three} 
    } 
} 
+0

Nếu bạn đi tuyến đường đó, bạn có thể tận dụng lợi thế của thực tế là 'doWork' luôn trả về' các đối tượng' để định nghĩa nó là trả về 'Object []'. Bằng cách này bạn có thể tránh một vài phôi trong 'main'. –

+0

@CyrilleKa điểm hợp lệ – chancea

Các vấn đề liên quan