Biểu thức Lambda để chuyển đổi mảng / Danh sách chuỗi thành mảng / Danh sách số nguyên


111

Vì Java 8 đi kèm với các biểu thức lambda mạnh mẽ,

Tôi muốn viết một hàm để chuyển đổi một Danh sách / mảng Chuỗi thành mảng / Danh sách số nguyên, số nổi, số đôi, v.v.

Trong Java thông thường, nó sẽ đơn giản như

for(String str : strList){
   intList.add(Integer.valueOf(str));
}

Nhưng làm cách nào để đạt được điều tương tự với lambda, với một mảng Chuỗi được chuyển đổi thành một mảng Số nguyên.

Câu trả lời:


128

Bạn có thể tạo các phương thức trợ giúp để chuyển đổi một danh sách (mảng) kiểu Tthành một danh sách (mảng) kiểu Ubằng cách sử dụng mapthao tác trên stream.

//for lists
public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) {
    return from.stream().map(func).collect(Collectors.toList());
}

//for arrays
public static <T, U> U[] convertArray(T[] from, 
                                      Function<T, U> func, 
                                      IntFunction<U[]> generator) {
    return Arrays.stream(from).map(func).toArray(generator);
}

Và sử dụng nó như thế này:

//for lists
List<String> stringList = Arrays.asList("1","2","3");
List<Integer> integerList = convertList(stringList, s -> Integer.parseInt(s));

//for arrays
String[] stringArr = {"1","2","3"};
Double[] doubleArr = convertArray(stringArr, Double::parseDouble, Double[]::new);


Lưu ý rằng s -> Integer.parseInt(s)có thể được thay thế bằng Integer::parseInt(xem Tham chiếu phương pháp )


5
Nếu bạn đang sử dụng Guava, bạn cũng có thể sử dụng Lists.transform().
Alexandros

Ví dụ rất tốt. Chức năng biến mã linh hoạt và mạnh mẽ hơn. Thks !!!
Marcelo Rebouças

127
List<Integer> intList = strList.stream()
                               .map(Integer::valueOf)
                               .collect(Collectors.toList());

5
Bạn có thể giải thích điều này một chút?
Unheilig

1
Đây là chuyển đổi danh sách Chuỗi thành một luồng sau đó ánh xạ / chuyển đổi mọi phần tử của danh sách thành Số nguyên sau đó thu thập thành danh sách.
hemanto

5
Đây phải là câu trả lời được chấp nhận, vì quan điểm của lambdas (câu hỏi ban đầu yêu cầu biểu thức lambda) là tránh xác định một hàm mới. Trên hết, câu trả lời này sử dụng một cách trang nhã hàm Integer :: valueOf hiện có
Jonathan Benn

31

Các phương thức trợ giúp từ câu trả lời được chấp nhận là không cần thiết. Luồng có thể được sử dụng với lambdas hoặc thường được rút ngắn bằng cách sử dụng Tham khảo phương pháp . Luồng cho phép các hoạt động chức năng. map()chuyển đổi các phần tử và collect(...)hoặc toArray()bọc luồng trở lại thành một mảng hoặc tập hợp.

Bài nói chuyện của Venkat Subramaniam (video) giải thích nó tốt hơn tôi.

1 Chuyển đổi List<String>sangList<Integer>

List<String> l1 = Arrays.asList("1", "2", "3");
List<Integer> r1 = l1.stream().map(Integer::parseInt).collect(Collectors.toList());

// the longer full lambda version:
List<Integer> r1 = l1.stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList());

2 Chuyển đổi List<String>sangint[]

int[] r2 = l1.stream().mapToInt(Integer::parseInt).toArray();

3 Chuyển đổi String[]sangList<Integer>

String[] a1 = {"4", "5", "6"};
List<Integer> r3 = Stream.of(a1).map(Integer::parseInt).collect(Collectors.toList());

4 Chuyển đổi String[]sangint[]

int[] r4 = Stream.of(a1).mapToInt(Integer::parseInt).toArray();

5 Chuyển đổi String[]sangList<Double>

List<Double> r5 = Stream.of(a1).map(Double::parseDouble).collect(Collectors.toList());

6 (tiền thưởng) Chuyển đổi int[]thànhString[]

int[] a2 = {7, 8, 9};
String[] r6 = Arrays.stream(a2).mapToObj(Integer::toString).toArray(String[]::new);

Tất nhiên là có thể có nhiều biến thể hơn.

Cũng xem phiên bản Ideone của những ví dụ này . Có thể bấm ngã ba rồi chạy để chạy trên trình duyệt.


7

CHỈNH SỬA: Như đã chỉ ra trong các nhận xét, đây là một phiên bản đơn giản hơn nhiều: Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() Bằng cách này, chúng tôi có thể bỏ qua toàn bộ chuyển đổi đến và từ một danh sách.


Tôi đã tìm thấy một giải pháp một dòng khác, nhưng nó vẫn khá chậm (mất khoảng 100 lần so với một chu kỳ - được thử nghiệm trên một mảng 6000 0)

String[] stringArray = ...
int[] out= Arrays.asList(stringArray).stream().map(Integer::parseInt).mapToInt(i->i).toArray();

Điều này làm gì:

  1. Arrays.asList () chuyển đổi mảng thành Danh sách
  2. .stream chuyển đổi nó thành Luồng (cần thiết để thực hiện một bản đồ)
  3. .map (Integer :: parseInt) chuyển đổi tất cả các phần tử trong luồng thành Số nguyên
  4. .mapToInt (i-> i) chuyển đổi tất cả các Số nguyên thành số nguyên (bạn không phải làm điều này nếu bạn chỉ muốn Số nguyên)
  5. .toArray () chuyển đổi Luồng trở lại một mảng

13
Bạn không cần phải bước 1 và 4:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
xehpuk

3

Đối với danh sách:

List<Integer> intList 
 = stringList.stream().map(Integer::valueOf).collect(Collectors.toList());

Đối với mảng:

int[] intArray = Arrays.stream(stringArray).mapToInt(Integer::valueOf).toArray();

2

Bạn cũng có thể dùng,

List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");

    Integer[] array = list.stream()
        .map( v -> Integer.valueOf(v))
        .toArray(Integer[]::new);

0

Tôi không tìm thấy nó trong các câu trả lời trước, vì vậy, với Java 8 và các luồng:

Chuyển đổi String[]thành Integer[]:

Arrays.stream(stringArray).map(Integer::valueOf).toArray(Integer[]::new)

-1

Ngoài ra - kiểm soát khi mảng chuỗi không có các phần tử:

Arrays.stream(from).filter(t -> (t != null)&&!("".equals(t))).map(func).toArray(generator) 

-1

Tôi đã sử dụng maptoInt () với hoạt động Lambda để chuyển đổi chuỗi thành Số nguyên

int[] arr = Arrays.stream(stringArray).mapToInt(item -> Integer.parseInt(item)).toArray();

-3

Arrays.toString (int []) phù hợp với tôi.


Tôi không trả lời câu hỏi: "Làm thế nào để đạt được điều này với lambdas".
Sergei Sirik,
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.