-
การ แปลงอาร์เรย์ให้เป็นArrayList
ในการแปลงอาร์เรย์เป็นArrayListนักพัฒนามักใช้วิธีนี้:
List<String> list = Arrays.asList(arr);Arrays.asList()จะส่งคืนวัตถุคลาสArrayListซึ่งเป็นคลาสคงที่ส่วนตัวภายใน(private static class)ของคลาสArraysและนี่ไม่ใช่คลาสคลาสjava.util.ArrayList.มีjava.util.Arrays.ArrayListวิธีset(),get(),contains()แต่ไม่มีวิธีการใด ๆ สำหรับการเพิ่มองค์ประกอบ ขนาดของมันได้รับการแก้ไขแล้ว หากต้องการสร้างของจริงjava.util.ArrayListให้ทำดังนี้:ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));ตัวสร้างคลาส
java.util.ArrayListสามารถใช้เป็นพารามิเตอร์อ็อบเจ็กต์ทั้งหมดที่ใช้อินเทอร์เฟซCollectionซึ่งการใช้งานนั้นสืบทอดมาจากคลาสjava.util.Arrays.ArrayList(คลาสสแตติกส่วนตัว ArrayList<E> ขยาย AbstractList<E> ใช้ RandomAccess, java.io.Serializable)
-
การตรวจสอบอาร์เรย์เพื่อหาค่าเฉพาะ
นักพัฒนามักจะทำสิ่งนี้:
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);รหัสใช้งานได้ แต่ไม่จำเป็นต้องแปลง
Listเป็นSet. การแปลงเป็นSetจะใช้เวลาเพิ่มเติม ที่จริงแล้วทุกอย่างนั้นง่าย:Arrays.asList(arr).contains(targetValue);หรือ
for(String s: arr){ if(s.equals(targetValue)) return true; } return false;วิธีแรกสั้นกว่ามาก
-
การลบองค์ประกอบออกจาก
Listในลูปพิจารณารหัสต่อไปนี้ที่จะลบองค์ประกอบในวง:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (int i = 0; i < list.size(); i++) { list.remove(i); } System.out.println(list);บทสรุป:
[b, d]นี่กลายเป็นความผิดพลาดร้ายแรง เมื่อองค์ประกอบถูกลบ ขนาด
Listจะลดลง และดัชนีองค์ประกอบจะเปลี่ยนไปดังนั้นให้หลีกเลี่ยงวิธีนี้หากคุณต้องการลบหลายองค์ประกอบในลูปโดยใช้ดัชนี
คุณอาจรู้ว่าการใช้ตัววนซ้ำเป็นวิธีแก้ปัญหาที่ถูกต้องสำหรับการลบองค์ประกอบในลูป และคุณรู้ว่าสไตล์ลูป
for-eachทำงานเหมือนกับตัววนซ้ำ แต่ก็ไม่ได้เป็นเช่นนั้นพิจารณารหัสต่อไปนี้:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) { if (s.equals("a")) list.remove(s); }เราจะได้รับConcurrentModificationException
สิ่งที่ถูกต้องที่ต้องทำคือ:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); Iterator<String> iter = list.iterator(); while (iter.hasNext()) { String s = iter.next(); if (s.equals("a")) { iter.remove(); } }
ในรูปแบบลูปnext()ต้องเรียกเมธอดนี้ ก่อนไฟล์remove().for-eachคอมไพลเลอร์จะเรียกเมธอดremove()จากนั้นเท่านั้นnext()ซึ่งจะทำให้เกิดข้อผิดConcurrentModificationExceptionพลาดArrayList.iterator()คุณ สามารถดูรหัส -
Hashtableขัดต่อHashMap.เนื่องจากการใช้งานที่สอดคล้องกันHashtableจึงเป็นชื่อของโครงสร้างข้อมูล
แต่ในJavaชื่อของโครงสร้างข้อมูลคือ
HashMap. ความแตกต่างที่สำคัญประการหนึ่งระหว่างHashtableและHashMapก็คือ มีHashtableการซิงโครไนซ์ ดังนั้นจึงไม่ควรใช้HashtableโดยHashMapที่ -
ใช้คอลเลกชันโดยไม่มีข้อจำกัดด้านเนื้อหา
В Java часто путают коллекции без ограничений по содержимому, и коллекции с маской по типу содержимого. К примеру, для множеств -
Setэто коллекция без ограничений по содержимому, аSet<?>— коллекция у которой все-таки есть ограничения, но эти ограничения ничего на самом деле не ограничивают. Рассмотрим следующий code, гдеListбез ограничений используется в качестве параметра метода:public static void add(List list, Object o){ list.add(o); } public static void main(String[] args){ List<String> list = new ArrayList<String>(); add(list, 10); String s = list.get(0); }Данный code выбросит исключение:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at …Использование коллекций без ограничений по содержимому очень опасно, потому что вы не можете быть уверенными в том что там лежит внутри. А для того чтобы понять всю глубину разницы между
Set,Set<?>иSet<Object>— почитайте вот эту и эту ссылки. -
Уровень доступа
Очень часто для полей класса разработчики используют модификатор доступа
public. Так проще получить meaning поля напрямую. Правильнее использовать How можно более ограниченный доступ к членам класса. ArrayListпротивLinkedListКогда разработчики не знают чем отличается
ArrayListотLinkedList, они используют первый в силу его большей известности. Однако, есть огромная разница в производительности между ними. На самом деле, выбор между ними должен быть продиктован их внутренними особенностями —ArrayListпозволяет быстро производить доступ к произвольному элементу массива, аLinkedList— быстро добавлять/удалять элементы в массиве. Почитайте статью по ссылке ArrayList vs. LinkedList чтобы понять причины их разной производительности.Mutable(Изменяемый) противImmutable(Неизменяемый)Неизменяемый an object имеет много преимуществ: простота, безопасность и т.д. Но он требует отдельного an object для каждого нового значения, и за слишком большое количество an objectов придется заплатить понижением производительности. Должен быть баланс при выборе между изменяемым и неизменяемым обьектом.
В основном чтобы избежать подготовки промежуточных an objectов используется изменяемый an object. Один из классических примеров это конкатенация большого количества строк. Если вы используете неизменяемый an object типа
String, то вы создаете много an objectов, которые сразу попадут в сборщик мусора. Это тратит время и энергию процессора, поэтому правильное решение это использование изменяемых обьектов (напримерStringBuilder).String result=""; for(String s: arr){ result = result + s; }Еще один пример использования изменяемых an objectов — передача такого an object в метод. Это позволит вернуть результат в нем же, без создания лишних an objectов. При работе с an objectми большого размера, к примеру коллекциями, передача коллекции в метод для сортировки и возвращение результата в другой коллекции приводит к совершенно излишнему расходу ресурсов. (Ответ пользователя dasblinkenlight на Stack Overflow).
-
Конструкторы классов
SuperиSub
ข้อผิดพลาดในการคอมไพล์นี้มีสาเหตุมาจากข้อเท็จจริงที่ว่าคลาสบรรพบุรุษไม่ได้กำหนดคอนสตรัคเตอร์เริ่มต้นไว้ ในJavaเว้นแต่คุณจะระบุตัวสร้างคลาสด้วยตัวเอง คอมไพลเลอร์จะสร้างตัวสร้างเริ่มต้นที่ไม่ต้องมีอาร์กิวเมนต์ ถ้าคอนสตรัคเตอร์ถูกอธิบายไว้ในคลาส
Superว่าSuper(String s){}คอมไพเลอร์เองก็จะไม่เพิ่มสิ่งใดเข้าไป นี่คือสิ่งที่เราเห็นในตัวอย่างของเราConstructor ของคลาส
Subไม่ว่าอันไหนก็ตาม จะเรียก Constructor เริ่มต้นของคลาสSuperเนื่องจากไม่มีการระบุอย่างอื่นอีก เนื่องจากไม่มีตัวสร้างเริ่มต้นในคลาสSuperสิ่งนี้จะทำให้เกิดข้อผิดพลาดในการคอมไพล์วิธีแก้ปัญหาแรกสำหรับปัญหานี้คือการเพิ่มคอนสตรัคเตอร์เริ่มต้นให้กับคลาส
Superpublic Super(){ System.out.println("Super"); }ตัวเลือกที่สองคือการลบคอนสตรัคเตอร์ที่เราอธิบายออกจากคลาส
Superเพื่อให้คอมไพเลอร์สร้างคอนสตรัคเตอร์เริ่มต้นและตัวเลือกสุดท้ายคือการเพิ่มการเรียก
super(value)ตัวสร้างคลาสSubเพื่อให้ตัวสร้างคลาสที่มีอยู่ถูกเรียกแทนตัวสร้างเริ่มต้นSuper -
" " หรือตัวสร้าง?
มีสองวิธีในการสร้างสตริง:
//1. использовать двойные кавычки String x = "abc";
//2. использовать конструктор String y = new String("abc");ความแตกต่างระหว่างพวกเขาคืออะไร?
คุณสามารถเข้าใจสิ่งนี้ได้จากตัวอย่างต่อไปนี้:
String a = "abcd"; String b = "abcd"; System.out.println(a == b); // True System.out.println(a.equals(b)); // True String c = new String("abcd"); String d = new String("abcd"); System.out.println(c == d); // False System.out.println(c.equals(d)); // Trueหากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการจัดเก็บสตริงในหน่วยความจำ โปรดอ่านสร้างสตริง Java โดยใช้ "" หรือ Constructor? .
theGrass
ระดับ
GO TO FULL VERSION