ฉันลองวนซ้ำแบบนั้น
// ArrayList tourists
for (Tourist t : tourists) {
if (t != null) {
t.setId(idForm);
}
}
แต่มันก็ไม่ดี ใครช่วยแนะนำฉันได้ดีกว่า
เกณฑ์มาตรฐานที่มีประโยชน์เพื่อการตัดสินใจที่ดีกว่า:
ฉันลองวนซ้ำแบบนั้น
// ArrayList tourists
for (Tourist t : tourists) {
if (t != null) {
t.setId(idForm);
}
}
แต่มันก็ไม่ดี ใครช่วยแนะนำฉันได้ดีกว่า
เกณฑ์มาตรฐานที่มีประโยชน์เพื่อการตัดสินใจที่ดีกว่า:
คำตอบ:
ลอง:
tourists.removeAll(Collections.singleton(null));
อ่านJava API รหัสจะโยนjava.lang.UnsupportedOperationException
สำหรับรายการที่ไม่เปลี่ยนรูป (เช่นสร้างด้วยArrays.asList
); ดูคำตอบนี้สำหรับรายละเอียดเพิ่มเติม
List.removeAll()
เป็นn ^ 2 แค่พูด.
O(n)
ให้ฉันเพื่อทั้งสองและArrayList
LinkedList
contains()
ลูปอาร์เรย์ทั้งหมด) และตั้งแต่เป็นเพียงองค์ประกอบหนึ่งมันจะเป็นsingleton
แต่โดยทั่วไปก็จะเป็นN * 1 = N
N^2
ตั้งแต่ปี 2015 นี่เป็นวิธีที่ดีที่สุด (Java 8):
tourists.removeIf(Objects::isNull);
หมายเหตุ:รหัสนี้จะjava.lang.UnsupportedOperationException
แสดงเป็นรายการขนาดคงที่ (เช่นสร้างด้วย Arrays.asList) รวมถึงรายการที่ไม่เปลี่ยนรูป
removeIf
มันจะเร็วกว่า แต่ก็เดาได้
Arrays.asList
ไม่ได้เปลี่ยนรูป ขนาดคงที่
list.removeAll(Collections.singleton(null));
มันจะโยนUnsupportedExceptionถ้าคุณใช้มันใน Arrays.asList เพราะมันให้สำเนาที่ไม่เปลี่ยนรูปดังนั้นคุณจึงไม่สามารถแก้ไขได้ ดูรหัสด้านล่าง มันสร้างสำเนาที่ไม่แน่นอนและจะไม่ทิ้งข้อยกเว้นใด ๆ
public static String[] clean(final String[] v) {
List<String> list = new ArrayList<String>(Arrays.asList(v));
list.removeAll(Collections.singleton(null));
return list.toArray(new String[list.size()]);
}
หากคุณต้องการวัตถุข้อมูลที่ไม่เปลี่ยนรูปแบบหรือถ้าคุณไม่ต้องการทำลายรายการอินพุตคุณสามารถใช้เพรดิเคตของ Guava
ImmutableList.copyOf(Iterables.filter(tourists, Predicates.notNull()))
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
removeAll(..null..)
องค์ประกอบกว่าพยายามที่จะใช้ ขอบคุณ!
Pre-Java 8 คุณควรใช้:
tourists.removeAll(Collections.singleton(null));
การใช้ Post-Java 8:
tourists.removeIf(Objects::isNull);
เหตุผลที่นี่คือความซับซ้อนของเวลา ปัญหาของอาร์เรย์คือการดำเนินการลบสามารถใช้เวลา O (n) ในการดำเนินการให้เสร็จสมบูรณ์ จริง ๆ ใน Java นี่คือสำเนาขององค์ประกอบที่เหลือจะถูกย้ายเพื่อแทนที่จุดที่ว่างเปล่า วิธีแก้ปัญหาอื่น ๆ ที่นำเสนอที่นี่จะทำให้เกิดปัญหานี้ อดีตคือเทคนิค O (n * m) โดยที่ m คือ 1 เพราะมันเป็นโมฆะเดี่ยว: ดังนั้น O (n)
คุณควรลบ singleton ทั้งหมดภายในมันจะทำการ batchRemove () ซึ่งมีตำแหน่งการอ่านและตำแหน่งการเขียน และวนซ้ำรายการ เมื่อมันชนกับโมฆะมันจะทำซ้ำตำแหน่งการอ่านโดย 1 เมื่อพวกมันเหมือนกันมันจะผ่านเมื่อมันต่างกันมันจะเคลื่อนที่ไปตามการคัดลอกค่า จากนั้นในตอนท้ายมันมีขนาด
มันทำสิ่งนี้ได้อย่างมีประสิทธิภาพภายใน:
public static <E> void removeNulls(ArrayList<E> list) {
int size = list.size();
int read = 0;
int write = 0;
for (; read < size; read++) {
E element = list.get(read);
if (element == null) continue;
if (read != write) list.set(write, element);
write++;
}
if (write != size) {
list.subList(write, size).clear();
}
}
ซึ่งคุณสามารถเห็นได้อย่างชัดเจนคือการดำเนินการ O (n)
สิ่งเดียวที่อาจเร็วกว่าคือถ้าคุณทำซ้ำรายการจากปลายทั้งสองด้านและเมื่อคุณพบค่าว่างคุณจะตั้งค่าของมันเท่ากับค่าที่คุณพบในตอนท้ายและลดค่านั้นลง และวนซ้ำจนกว่าค่าทั้งสองจะจับคู่ คุณต้องการทำให้คำสั่งซื้อยุ่งเหยิง แต่จะลดจำนวนของค่าที่คุณตั้งไว้อย่างมากเมื่อเทียบกับค่าที่คุณทิ้งไว้ตามลำพัง ซึ่งเป็นวิธีที่ดีที่จะรู้ แต่จะไม่ช่วยอะไรมากเท่าที่. set () นั้นฟรี แต่การลบรูปแบบนั้นเป็นเครื่องมือที่มีประโยชน์สำหรับสายพานของคุณ
for (Iterator<Tourist> itr = tourists.iterator(); itr.hasNext();) {
if (itr.next() == null) { itr.remove(); }
}
ในขณะที่สิ่งนี้ดูเหมือนว่ามีเหตุผลเพียงพอการลบ () บนตัววนซ้ำภายในจะเรียก:
ArrayList.this.remove(lastRet);
ซึ่งเป็นการดำเนินการ O (n) อีกครั้งภายในการลบ มันทำ System.arraycopy () ซึ่งไม่ใช่สิ่งที่คุณต้องการอีกครั้งถ้าคุณสนใจความเร็ว นี่ทำให้มันเป็น n ^ 2
นอกจากนี้ยังมี:
while(tourists.remove(null));
อันไหนคือ O (m * n ^ 2) ที่นี่เราไม่เพียง แต่ย้ำรายการ เราย้ำรายการทั้งหมดทุกครั้งที่เราจับคู่ค่าว่าง จากนั้นเราทำการดำเนินการ n / 2 (โดยเฉลี่ย) เพื่อทำ System.arraycopy () เพื่อทำการลบ คุณสามารถเรียงลำดับคอลเลกชันทั้งหมดระหว่างรายการที่มีค่าและรายการที่มีค่า Null และตัดส่วนที่ลงท้ายด้วยเวลาที่น้อยลง ในความเป็นจริงมันเป็นเรื่องจริงสำหรับคนที่เสียทั้งหมด อย่างน้อยก็ในทางทฤษฎีแล้วระบบที่แท้จริงการจัดการคัดลอกไม่ใช่การปฏิบัติงานจริงในทางปฏิบัติ ในทางทฤษฎีทฤษฎีและการปฏิบัติเป็นสิ่งเดียวกัน ในทางปฏิบัติพวกเขาไม่ได้
มีวิธีที่ง่ายในการลบnull
ค่าทั้งหมดออกจากcollection
คุณต้องผ่านคอลเลกชันที่มีค่า null เป็นพารามิเตอร์ไปยังremoveAll()
วิธีการ
List s1=new ArrayList();
s1.add(null);
yourCollection.removeAll(s1);
Objects
ชั้นมีnonNull
Predicate
ที่สามารถนำมาใช้กับfilter
ที่สามารถนำมาใช้กับ
ตัวอย่างเช่น:
tourists.stream().filter(Objects::nonNull).collect(Collectors.toList());
การใช้ Java 8 คุณสามารถทำได้โดยใช้stream()
และfilter()
tourists = tourists.stream().filter(t -> t != null).collect(Collectors.toList())
หรือ
tourists = tourists.stream().filter(Objects::nonNull).collect(Collectors.toList())
สำหรับข้อมูลเพิ่มเติม: Java 8 - Streams
นี่เป็นวิธีที่ง่ายในการลบค่า Null เริ่มต้นจาก arraylist
tourists.removeAll(Arrays.asList(null));
มิฉะนั้นค่าสตริง "null" จะถูกลบออกจากรายการอาร์เรย์
tourists.removeAll(Arrays.asList("null"));
ฉันเล่นกับสิ่งนี้และพบว่า trimToSize () ดูเหมือนว่าจะใช้งานได้ ฉันกำลังทำงานบนแพลตฟอร์ม Android ดังนั้นจึงอาจแตกต่างกัน
trimToSize
ArrayList
หากนี่เป็น Android ที่แตกต่างกันมันอาจเป็นข้อผิดพลาด
เราสามารถใช้ตัววนซ้ำเดียวกันเพื่อลบค่า Null ทั้งหมด
Iterator<Tourist> itr= tourists.iterator();
while(itr.hasNext()){
if(itr.next() == null){
itr.remove();
}
}
ฉันใช้ส่วนต่อประสานกระแสกับการรวบรวมกระแสข้อมูลและวิธีช่วยในการสร้างรายการใหม่
tourists.stream().filter(this::isNotNull).collect(Collectors.toList());
private <T> boolean isNotNull(final T item) {
return item != null;
}
tourists.stream().filter(s -> s != null).collect(Collectors.toList());
ส่วนใหญ่ฉันใช้สิ่งนี้:
list.removeAll(Collections.singleton(null));
แต่หลังจากที่ฉันเรียนรู้ Java 8 ฉันเปลี่ยนมาใช้สิ่งนี้:
List.removeIf(Objects::isNull);
การใช้Java 8สามารถดำเนินการได้หลายวิธีโดยใช้สตรีมสตรีมขนานและremoveIf
เมธอด:
List<String> stringList = new ArrayList<>(Arrays.asList(null, "A", "B", null, "C", null));
List<String> listWithoutNulls1 = stringList.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList()); //[A,B,C]
List<String> listWithoutNulls2 = stringList.parallelStream()
.filter(Objects::nonNull)
.collect(Collectors.toList()); //[A,B,C]
stringList.removeIf(Objects::isNull); //[A,B,C]
สตรีมแบบขนานจะใช้ประโยชน์จากโปรเซสเซอร์ที่มีอยู่และจะเร่งกระบวนการสำหรับรายการขนาดที่เหมาะสม ขอแนะนำให้ใช้เกณฑ์มาตรฐานก่อนใช้สตรีมเสมอ
คล้ายกับ @Lithium answer แต่ไม่โยนข้อผิดพลาด "List อาจไม่มีประเภท null":
list.removeAll(Collections.<T>singleton(null));
List<String> colors = new ArrayList<>(
Arrays.asList("RED", null, "BLUE", null, "GREEN"));
// using removeIf() + Objects.isNull()
colors.removeIf(Objects::isNull);
Iterator
หรือไม่ ขุด java-doc download.oracle.com/javase/6/docs/api/java/util/…