นิพจน์แลมบ์ดาเพื่อแปลงอาร์เรย์ / รายการสตริงเป็นอาร์เรย์ / รายการจำนวนเต็ม


111

เนื่องจาก Java 8 มาพร้อมกับนิพจน์แลมด้าอันทรงพลัง

ฉันต้องการเขียนฟังก์ชันเพื่อแปลง List / array ของ Strings เป็น array / List of Integers, Floats, Doubles ฯลฯ ..

ใน Java ปกติมันจะง่ายพอ ๆ กับ

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

แต่ฉันจะบรรลุสิ่งเดียวกันกับแลมด้าได้อย่างไรโดยกำหนดอาร์เรย์ของสตริงที่จะแปลงเป็นอาร์เรย์ของจำนวนเต็ม

คำตอบ:


128

คุณสามารถสร้างวิธีการช่วยเหลือที่จะแปลงรายการ (อาร์เรย์) ประเภทTไปยังรายการ (อาร์เรย์) ประเภทUการใช้การดำเนินการเกี่ยวกับmapstream

//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);
}

และใช้มันดังนี้:

//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);


โปรดทราบว่า s -> Integer.parseInt(s)สามารถแทนที่ด้วยInteger::parseInt(ดูการอ้างอิงวิธีการ )


5
หากคุณใช้ Guava คุณสามารถใช้Lists.transform()ไฟล์.
Alexandros

ตัวอย่างที่ดีมาก ฟังก์ชั่นเปลี่ยนรหัสได้หลากหลายและมีประสิทธิภาพมากขึ้น ขอบคุณ !!!
Marcelo Rebouças

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

5
ช่วยอธิบายเรื่องนี้หน่อยได้ไหม
Unheilig

1
นี่คือการแปลงรายการ String เป็นสตรีมจากนั้นทำการแมป / แปลงทุกองค์ประกอบของรายการเป็นจำนวนเต็มจากนั้นรวบรวมลงในรายการ
hemanto

5
นี่ควรเป็นคำตอบที่ยอมรับได้เนื่องจากประเด็นของ lambdas (คำถามเดิมถามถึงการแสดงออกของแลมบ์ดา) คือการหลีกเลี่ยงการกำหนดฟังก์ชันใหม่ ยิ่งไปกว่านั้นคำตอบนี้ใช้ฟังก์ชัน Integer :: valueOf ที่มีอยู่อย่างหรูหรา
Jonathan Benn

31

ไม่จำเป็นต้องใช้วิธีการช่วยเหลือจากคำตอบที่ยอมรับ ลำธารสามารถใช้กับ lambdas หรือสั้นลงโดยใช้มักจะวิธีการอ้างอิง สตรีมเปิดใช้งานฟังก์ชันการทำงาน map()แปลงองค์ประกอบและcollect(...)หรือtoArray()รวมสตรีมสำรองไว้ในอาร์เรย์หรือคอลเลกชัน

การพูดคุย (วิดีโอ) ของ Venkat Subramaniamอธิบายได้ดีกว่าฉัน

1 แปลงList<String>เป็นList<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 แปลงList<String>เป็นint[]

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

3 แปลงString[]เป็นList<Integer>

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

4 แปลง String[]เป็นint[]

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

5 แปลง String[]เป็นList<Double>

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

6 (โบนัส) แปลง int[]เป็นString[]

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

แน่นอนว่ามีรูปแบบอื่น ๆ อีกมากมาย

ดูเวอร์ชันของ Ideone ของตัวอย่างเหล่านี้ด้วย สามารถคลิก fork แล้วเรียกใช้เพื่อรันในเบราว์เซอร์


7

แก้ไข: ตามที่ระบุไว้ในความคิดเห็นนี่เป็นเวอร์ชันที่ง่ายกว่ามาก: Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() วิธีนี้เราสามารถข้ามการแปลงทั้งหมดไปและกลับจากรายการได้


ฉันพบโซลูชันหนึ่งบรรทัดอื่น แต่ก็ยังค่อนข้างช้า (ใช้เวลาประมาณ 100 กว่ารอบการทดสอบ - ทดสอบกับอาร์เรย์ 6000 0)

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

สิ่งนี้ทำอะไร:

  1. Arrays.asList () แปลงอาร์เรย์เป็นรายการ
  2. .stream แปลงเป็นสตรีม (จำเป็นในการดำเนินการแผนที่)
  3. .map (Integer :: parseInt) แปลงองค์ประกอบทั้งหมดในสตรีมเป็นจำนวนเต็ม
  4. .mapToInt (i-> i) แปลงจำนวนเต็มทั้งหมดเป็น ints (คุณไม่จำเป็นต้องทำสิ่งนี้หากคุณต้องการเพียงจำนวนเต็ม)
  5. .toArray () แปลงสตรีมกลับเป็นอาร์เรย์

13
คุณไม่จำเป็นต้องมีขั้นตอนที่ 1 และ 4:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
xehpuk


2

คุณยังสามารถใช้

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

ฉันไม่พบในคำตอบก่อนหน้าดังนั้นด้วย Java 8 และสตรีม:

แปลงString[]เป็นInteger[]:

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

-1

นอกจากนี้ - ควบคุมเมื่ออาร์เรย์สตริงไม่มีองค์ประกอบ:

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

-1

ฉันใช้ maptoInt () กับการดำเนินการ Lambda สำหรับการแปลงสตริงเป็นจำนวนเต็ม

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.