コレクションシステム3つのコア規則

図コレクション一般的なクラス:

注:地図コレクションインタフェース気付いていません

収集システム

次のカテゴリの十分注意します:

/**
 * @see     Set
 * @see     List
 * @see     Map
 * @see     SortedSet
 * @see     SortedMap
 * @see     HashSet
 * @see     TreeSet
 * @see     ArrayList
 * @see     LinkedList
 * @see     Vector
 * @see     Collections
 * @see     Arrays
 * @see     AbstractCollection
 */

各メソッドコレクションの意味を理解する:デフォルトの方法は、後にJava8を含み

public interface Collection<E> extends Iterable<E> {
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    <T> T[] toArray(T[] a);
    boolean add(E e);
    boolean remove(Object o);
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    boolean removeAll(Collection<?> c);
    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }
    boolean retainAll(Collection<?> c);
    void clear();
    boolean equals(Object o);
    int hashCode();
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

配列/コレクションユーティリティメソッド

一般に、Xは、工具のXメソッドに関連付けられているクラスである場合:

  • アレイ - >アレイ
  • コレクション - >コレクション
  • 一覧 - >リスト(グアバ)
  • セット - >セット(グアバ)

方法のいくつかのコレクション:

Collections.emptyList():
- 返回一个final的空List,这个List是一个内部类EmptyList的实例

Collections.synchronizedList(list):
- 装饰器模式,返回一个SynchronizedList的实例,这个类将list的每个方法都用synchronized包装起来了

Collections.unmodifiableList():
- 返回一个UnmodifiableList的实例,对这个实例的修改操作,都会抛出UnsupportedOperationException

Collections.sort(List<T> list):
Collections.sort(List<T> list, Comparator<? super T> c):
- 排序,实际上就是调用了list自己的sort,直接修改原list,没有返回值

还有一些checkXX和singletonXX等之类的方法

いくつかのコレクション内部クラス:

上記方法で使用されるような内部クラスは、実質的に

AbstractCollection

AbstractCollectionスケルトンは使用して、コレクションインタフェースを提供するために実装されます模板方法模式

例えば:

Collection定义了size()和isEmpty()这两个方法

在AbstractCollection中,isEmpty()的实现是:return size() == 0;
这样子,大部分AbstractCollection的子类就不需要自己再实现一遍isEmpty()方法了,
当然,子类也可以选择覆盖isEmpty()方法,以提供自己的实现。

そして、:

contains(Object o) 方法,判断一个元素是否在这个集合中,调用了 iterator 来获取子类的迭代器,然后迭代集合内的元素进行比较。
toArray、remove、removeAll、retainAll、clear、toString等方法也调用了iterator

也存在模板方法相互调用的情况:containsAll -> contains

テンプレートメソッドパターンに加えて、AbstractCollection自体は、いくつかのデフォルトの実装を提供します。

add()方法的现实是:throw new UnsupportedOperationException();

AbstractList、同様のAbstractSet

Q:私たちは、Collectionインタフェースで定義されたメソッドのいくつかは、AbstractCollectionが再びとして宣言されることに注意してソースコードを見てabstract、これはなぜですか?

これらのメソッドを反映させるためには抽象的ですか?これらのメソッドはデフォルトを提供実装する防ぐためやインターフェイスには?

A:TODO

その他:

接口与接口、类与类之间用extends
类与接口用implements


如果接口有default方法a()
抽象类又将a()声明成抽象的
那么实现类还是需要覆盖a()

コア大会収集システム

等しいです:

  • 再帰:再帰について、x.equals(x)は==真
  • 対称性:対称について、x.equals(Y)== y.equals(X)
  • 推移:推移について、x.equals(Y)== trueを、y.equals(Z)== trueの場合に、x.equals(z)は== trueの場合
  • 一貫性:一貫性について、x.equals(y)は、戻り値が変更されていない、それを呼び出し回数に関係なくは、前提は、情報を変更するために使用等しい方法ではありません
  • 任意の非ヌルオブジェクトxについてについて、x.equals(NULL)==偽

Object.equals():

  • これは再帰的である:null以外の参照値xについてについて、x.equals(x)がtrueを返します。
  • それは対称である:任意の非ヌル参照値xおよびyについてについて、x.equals(y)はy.equals(x)がtrueを返す場合にのみtrueを返すべきです。
  • それは推移的である:任意の基準値は、xの非ヌル、Y、及びZのためにについて、x.equals(y)が真とy.equals(z)を返した場合にtrueを返す場合に、x.equals(z)がtrueを返すべきです。
  • それは一貫している:任意の非ヌル参照値xおよびyについて、x.equals(y)の複数の呼び出し一貫してfalseを返すtrueを返すか、一貫して、改変されたオブジェクトの等号の比較に使用される情報を全く設けられていません。
  • 任意の非ヌル参照値xに対してについて、x.equals(ヌル)がfalseを返すべきです。

ハッシュコード:

  • 同期間JVMでは、かかわらず、hashCodeの回数コールの同じオブジェクト、戻りint型は、メソッドがするために使用される情報を変更しないと等しいことを提供し、同じでなければなりません。
  • 若x.equals(Y)== trueを、则x.hashCode()== y.hashCode()
  • x.equals(Y)== falseを、次いでx.hashCode()とy.hashCode()は必須の不均等ではない場合。
    • しかし、プログラマは、2つのオブジェクトのunequalsため、ハッシュコードの戻り異なる値がパフォーマンスハッシュテーブルを向上させることができることを理解すべきです

Object.hashCode():

  • オブジェクトが変更された上で、それは、Javaアプリケーションの実行中に複数回同じオブジェクトで呼び出されるたびに、hashCodeメソッドは一貫して同じ整数を返す必要があり、等号の比較に使用される情報を全く設けられていません。この整数は同じアプリケーションの別の実行へのアプリケーションの1つの実行の一貫性を維持する必要はありません。
  • 2つのオブジェクトが等しい(オブジェクト)の方法に従って等しい場合には、同じ整数の結果を生成しなければならない二つの物体の各々にhashCodeメソッドを呼び出します。
  • 2つのオブジェクトが等しい(オブジェクト)の方法に従って等しくない場合、2つのオブジェクトのそれぞれにhashCodeメソッドを呼び出すと異なる整数の結果を生成しなければならないことが要求されません。しかし、プログラマは、等しくないオブジェクトについては異なる整数値が生成するハッシュテーブルの性能を向上させることができることに注意すべきです。

匹敵する/コンパレータ:

  • 各実装Comparableクラスインターフェイスは、全体的な分類を達成することが必須です。この順序は自然順序付けクラス、その自然の比較方法と呼ばれるクラスのcompareToメソッドと呼ばれています。
    • (すなわち、compareToメソッドは、そのような追加のコンパレータを使用するように、クラスは、自然な順序の並べ替え、または使用しません)
  • 実装 Comparableオブジェクトリスト又はアレイのインタフェースとすることができるCollections.sort(とArrays.sort)自動的にソート。この目的を達成するために、インターフェイスをするために使用することができるSortedMapキーまたはSortedSet比較を指定することなく、要素。
  • 任意のオブジェクトクラスCのE1、E2のため、およびのみがe1.compareTo(E2)== 0とe1.equals(E2)場合は、同じ値を返し、Cは自然な順序と一致等しいと呼ぶことができます。
    • 注:ヌルはどのクラスのインスタンスではありません、e.compareTo(ヌル)がスローする必要がありますNullPointerExceptione.equals(ヌル)がfalseを返した場合でも、。
  • 強く、自然順序付けがequalsと一貫性があるようにすることをお勧めします。自然順序付けを使用して、それらの要素(またはキー)がequalsと矛盾している、と指定されていないので、これは余分ComparatorSortedSet(とSortedMap)行動は『奇妙な。』となりました 具体的には、このSortedSet(またはSortedMapequalsメソッドの用語で定義された)セット(またはマップ)違反従来の慣例。
  • たとえば、次のように...(例の後ろ)
  • 実際には、すべての実現ComparableのJavaコアクラスは、自然順序付けがequalsと一貫している必要があります。java.math.BigDecimal彼は、値が等しいが、種々の精度例外、その自然な順序でBigDecimal(例えば4.0や4.00など)オブジェクトが等しいと見なされます。

同程度の:

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.

Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort). Objects that implement this interface can be used as keys in a sorted map or as elements in a sorted set, without the need to specify a comparator.

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.

It is strongly recommended (though not required) that natural orderings be consistent with equals. This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.

For example, if one adds two keys a and b such that (!a.equals(b) && a.compareTo(b) == 0) to a sorted set that does not use an explicit comparator, the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set's perspective.

Virtually all Java core classes that implement Comparable have natural orderings that are consistent with equals. One exception is java.math.BigDecimal, whose natural ordering equates BigDecimal objects with equal values and different precisions (such as 4.0 and 4.00).

For the mathematically inclined, the relation that defines the natural ordering on a given class C is:
         {(x, y) such that x.compareTo(y) <= 0}.
   
The quotient for this total order is:
         {(x, y) such that x.compareTo(y) == 0}.
   
It follows immediately from the contract for compareTo that the quotient is an equivalence relation on C, and that the natural ordering is a total order on C. When we say that a class's natural ordering is consistent with equals, we mean that the quotient for the natural ordering is the equivalence relation defined by the class's equals(Object) method:
       {(x, y) such that x.equals(y)}. 

同等の正しい使い方:

// 实现Comparable接口,重写compareTo方法。这里只比较age
public class User implements Comparable<User> {
    int id;
    int age;
    @Override
    public int compareTo(User that) {
        // 小于就返回-1,大于就返回1,等于就返回0
        if (age < that.age) {
            return -1;
        } else if (age > that.age) {
            return 1;
        } else {
            return 0;
        }
        // 每种基本类型都会有现成的比较器,一般不需要自己写
        // return Integer.compare(age, that.age);
    }
}

トリッキー質問:

// compareTo只需要返回正数、负数或0,并不一定要返回1、-1,所以有的人就会使用相减来实现
@Override
public int compareTo(User that) {
    return age - that.age;
}
// 这会有什么问题呢?
// 整数溢出问题,如果 age = Integer.MIN_VALUE,that.age = Integer.MAX_VALUE,
// 那么 age - that.age = 1

// 以及不要使用非/取反操作
// age = Integer.MIN_VALUE
// -age = -2147483648

だから、:それは数値につながる可能性としてDoが、のcompareToを達成するために、加算、減算、否定を使用しないオーバーフロー

そして、自然順序付けの例は、equalsと矛盾しています。

public class User implements Comparable<User> {
    int id;
    int age;
    public User(int id, int age) {
        this.id = id;
        this.age = age;
    }
    @Override
    public int hashCode() {
        return Objects.hash(id, age);
    }
    
    // equals比较了id和age
    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null || getClass() != that.getClass()) {
            return false;
        }
        User user = (User) that;
        return id == user.id &&
                age == user.age;
    }
    // compareTo只比较了age
    @Override
    public int compareTo(User that) {
        return Integer.compare(age, that.age);
    }
    public static void main(String[] args) {
        // 1号user与3号user unequals,即!user1.equals(user3)
        // user1.compareTo(user3) == 0
        // 而 SortedSet(TreeSet) 内部是使用compareTo进行比较的,那么user1与user3是相等的,所以add不进去
        Set<User> set = new TreeSet<>();
        set.add(new User(1, 20));
        set.add(new User(2, 10));
        set.add(new User(3, 20));
        // [User{id=2, age=10}, User{id=1, age=20}]
        System.out.println(set);
    }
}

コレクション内のequalsとhashCodeはどこで使用しました

ALL

おすすめ

転載: www.cnblogs.com/demojie/p/12596132.html