-
配列を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
との主な違いの 1 つは、同期される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){}
、コンパイラー自体は何も追加しません。これがこの例で見られるものです。他に何も指定されていないため、 class のコンストラクターは、どれであっても、
Sub
class のデフォルトのコンストラクターを呼び出しますSuper
。class にはデフォルトのコンストラクターがないためSuper
、コンパイル エラーが発生します。この問題に対する最初の解決策は、デフォルトのコンストラクターをクラスに追加することです。
Super
public Super(){ System.out.println("Super"); }
Super
2 番目のオプションは、コンパイラーがデフォルトのコンストラクターを作成するように、説明したコンストラクターをクラスから削除することです。最後のオプションは、
super(value)
クラス コンストラクターへの呼び出しを追加してSub
、デフォルトのコンストラクターの代わりに既存のクラス コンストラクターが呼び出されるようにすることです。Super
-
" " またはコンストラクター?
文字列を作成するには 2 つの方法があります。
//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 文字列を作成する」を参照してください。。
GO TO FULL VERSION