JavaRush /Java Blog /Random-JA /Java 開発者がよく犯す 10 の間違い
theGrass
レベル 24
Саратов

Java 開発者がよく犯す 10 の間違い

Random-JA グループに公開済み
Java 開発者がよく犯す 10 の間違い - 1
このリストには、Java開発者がよく犯す 10 の間違いが含まれています。
  1. 配列をArrayListに変換します。

    配列をArrayListに変換するために、開発者はよくこのメソッドを使用します。

    List<String> list = Arrays.asList(arr);

    Arrays.asList()は、クラスのArrayList内部プライベート静的クラスであるクラス オブジェクトを返します。これはクラスではありません。クラスにはメソッド、、が含まれますが、要素を追加するメソッドは含まれません。サイズは固定です。実際のものを作成するには、次のようにします。(private static class)Arraysjava.util.ArrayList.java.util.Arrays.ArrayListset()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 を実装します)。

  2. 配列の特定の値をチェックします。

    開発者はよくこれを行います。

    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;

    最初の方法ははるかに短いです。

  3. 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()

  4. Hashtableに対してHashMap

    対応する実装により、Hashtable はデータ構造の名前になります。

    しかし、Javaではデータ構造の名前は ですHashMapHashtableとの主な違いの 1 つは、同期されるHashMapことです。そのため、の場所でHashtableは使用しないでください。HashtableHashMap

    ハッシュマップ vs. ツリーマップと ハッシュテーブル vs. LinkedHashMap

    Map インターフェイスに関する 10 の基本的な質問

  5. コンテンツ制限なしでコレクションを使用する

    В 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> — почитайте вот эту и эту ссылки.

  6. Уровень доступа

    Очень часто для полей класса разработчики используют модификатор доступа public. Так проще получить meaning поля напрямую. Правильнее использовать How можно более ограниченный доступ к членам класса.

    public, default, protected, and private.

  7. ArrayList против LinkedList

    Когда разработчики не знают чем отличается ArrayList от LinkedList, они используют первый в силу его большей известности. Однако, есть огромная разница в производительности между ними. На самом деле, выбор между ними должен быть продиктован их внутренними особенностями — ArrayList позволяет быстро производить доступ к произвольному элементу массива, а LinkedList — быстро добавлять/удалять элементы в массиве. Почитайте статью по ссылке ArrayList vs. LinkedList чтобы понять причины их разной производительности.

  8. 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).

    Почему an object класса String неизменяем?

  9. Конструкторы классов Super и Sub

    Java 開発者がよく犯す 10 の間違い - 2

    このコンパイル エラーは、祖先クラスにデフォルトのコンストラクターが定義されていないことが原因で発生します。Javaでは、クラス コンストラクターを自分で指定しない限り、コンパイラーは引数を必要としないデフォルトのコンストラクターを作成します。コンストラクターがクラス内にSuperとして記述されている場合Super(String s){}、コンパイラー自体は何も追加しません。これがこの例で見られるものです。

    他に何も指定されていないため、 class のコンストラクターは、どれであっても、 Subclass のデフォルトのコンストラクターを呼び出しますSuper。class にはデフォルトのコンストラクターがないためSuper、コンパイル エラーが発生します。

    この問題に対する最初の解決策は、デフォルトのコンストラクターをクラスに追加することです。Super

    public Super(){
        System.out.println("Super");
    }

    Super2 番目のオプションは、コンパイラーがデフォルトのコンストラクターを作成するように、説明したコンストラクターをクラスから削除することです。

    最後のオプションは、super(value)クラス コンストラクターへの呼び出しを追加してSub、デフォルトのコンストラクターの代わりに既存のクラス コンストラクターが呼び出されるようにすることです。Super

    スーパーとサブのコンストラクター

  10. " " またはコンストラクター?

    文字列を作成するには 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 文字列を作成する」を参照してください。

今後の計画。 このリストは、GitHub からの膨大な数のオープンソース プロジェクト、Stack Overflow からの質問、Google で人気のあるクエリの分析に基づいています。これらが実際に最も深刻な 10 の間違いに含まれるかどうかを証明するつもりはありませんが、実際には非常に一般的です。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION