JAVA——集合(Set)

16062 ワード

Set
要素は無秩序(格納と取り出しの順序が必ずしも一致しない)であり、要素は繰り返してはならない.
HashSet
下位データ構造はハッシュテーブルです.スレッドが安全ではありません.スレッドは非同期です.
HashSetはどのようにして要素の一意性を保証しますか?要素の2つの方法,hashCodeとequalsによって完成した.要素のHashCode値が同じ場合、equalsがtrueであるかどうかを判断します.要素のhashcode値が異なる場合、equalsは呼び出されません.なお,要素が存在するか否かの判断や削除などの操作には,要素のhashcodeやequalsメソッドが依存する.Setコレクションの機能はCollectionと一致している.
import java.util.*;
class HashSetDemo 
{
    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
    public static void main(String[] args) 
    {

        HashSet hs = new HashSet();

        sop(hs.add("java01"));
        sop(hs.add("java01"));
        hs.add("java02");
        hs.add("java03");
        hs.add("java03");
        hs.add("java04");

        Iterator it = hs.iterator();

        while(it.hasNext())
        {
            sop(it.next());
        }
    }
}

true false java04 java03 java02 java01
/*  hashSet          。            。 */
import java.util.*;
class HashSetTest
{
    public static void main(String[] args)
    {
        HashSet hs = new HashSet();
        hs.add(new Person("a1",11));
        hs.add(new Person("a2",12));
        hs.add(new Person("a3",13));
        hs.add(new Person("a2",12));


        //sop("a1:"+hs.contains(new Person("a2",12)));
        //hs.remove(new Person("a3",13));

        Iterator it = hs.iterator();
        while(it.hasNext())
        {
            Person p = (Person)it.next();
            sop(p.getName()+"......"+p.getAge());
        }
    }

    public static void sop(Object obj)
    {
        System.out.println(obj);
    }


}

class Person
{
    private String name;
    private int age;
    Person(String name,int age)
    {
        this.name = name;
        this.age = age;
    }

    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }

    public boolean equals(Object obj)
    {
        if(!(obj instanceof Person))
            return false;
        Person p = (Person)obj;
        System.out.println(this.name+"...equals..."+p.name);
        return this.name.equals(p.name)&&this.age==p.age;
    }
    public int hashCode()
    {
        System.out.println(this.name+"......hashCode");
        return name.hashCode()+age*37;      //    hash    ;
    }

}

結果:a 1......hashCode a 2......hashCode a 3......hashCode a 2......hashCode a 2...equals...a 2 a 3......13 a 1......11 a 2......12
まずHashSetがequalsを行う前にhashCodeの判断を先に行うことを明らかにしなければならないが,これはArrayListとは異なり,ArrayListはequalsメソッドを呼び出すだけである.最初はa 1,a 2,a 3のハッシュ値が異なり,hashCodeメソッドのみが呼び出されたため,直接出力する.a 2が再び現れると,hashCodeの呼び出しに加えてequalsメソッドを比較する.
加入するとき
sop("a1:"+hs.contains(new Person("a2",12)));
hs.remove(new Person("a3",13));

hashCodeが先に呼び出され,equalsメソッドが同じように呼び出されることが分かった.
TreeSet
Set集合中の要素を並べ替えることができる下位データ構造は、ツリーが要素の一意性を保証するcomparaToメソッドreturn 0.TreeSetに従って並べ替える第1の方法で、要素自体に比較性を持たせる.要素はcomparableインタフェースを実装し、compareToメソッドを上書きする必要があります.この方法は、要素の自然な順序、またはデフォルトの順序とも呼ばれます.TreeSetソートの第2の方式は,要素自身が比較性を持たない場合や,備える比較性が必要でない場合に集合自身に比較性を持たせる必要がある.集合初期化時に比較方式があります.コンパレータオブジェクトをパラメータとしてTreeSetセットのコンストラクション関数に渡します.両方のソートが存在する場合、コンパレータが主です.クラスを定義し、Comparatorインタフェースを実装し、comparareメソッドを上書きします.
1つ目の方法としては、次のようなものがあります.
lass TreeSetDemo
{
    public static void main(String[] args)
    {
        TreeSet ts = new TreeSet();
        ts.add("cba");
        ts.add("aaa");
        ts.add("bca");
        ts.add("abcd");
        Iterator it = ts.iterator();
        while(it.hasNext())
        sop(it.next());
    }
    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
}

出力結果:aaa abcd bca cbaをASCIIコードサイズでソート
class TreeSetDemo {
    public static void main(String[] args)
    {
        TreeSet ts = new TreeSet();
        ts.add(new Student("lisi02",22));
        ts.add(new Student("lisi03",20));
        ts.add(new Student("lisi06",19));

        Iterator it = ts.iterator();
        while(it.hasNext())
        {
            Student stu = (Student)it.next();
            sop(stu.getName()+"......"+stu.getAge());
        }

    }
    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
}


class Student implements Comparable //              {
    private String name;
    private int age;
    Student(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
    public int compareTo(Object obj)
    {
            return 1;
    }
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
}

結果:lisi 02・・・22 lisi 03・・・20 lisi 06・・・19
public int compareTo(Object obj);
  1 ,       
  -1 ,       
  0 ,      ,      ,    。

2つ目の例は、
import java.util.*;
class TreeSetDemo2
{
    public static void main(String[] args)
    {
        TreeSet ts = new TreeSet(new MyCompare());
        ts.add(new Student("lisi02",22));
        ts.add(new Student("lisi03",20));
        ts.add(new Student("lisi06",19));
        ts.add(new Student("lisi03",21));

        Iterator it = ts.iterator();
        while(it.hasNext())
        {
            Student stu = (Student)it.next();
            sop(stu.getName()+"......"+stu.getAge());
        }

    }
    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
}
class Student implements Comparable //              {
    private String name;
    private int age;
    Student(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
    public int compareTo(Object obj)
    {

        if(!(obj instanceof Student))
            throw new RuntimeException("     ");
        Student stu = (Student)obj; //System.out.println(this.name+"...compareTo..."+stu.name);
        if(this.age > stu.age)
            return 1;
         if(this.age == stu.age)
         {
             return this.name.compareTo(stu.name);
         }
            return -1;
    }
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
}
class MyCompare implements Comparator {
    public int compare(Object o1,Object o2)
    {
        Student stu1 = (Student)o1;
        Student stu2 = (Student)o2;
        int num= stu1.getName().compareTo(stu2.getName());
        if(num==0)
        {
            return new Integer(stu1.getAge()).compareTo (new Integer(stu2.getAge()));
        }
        /* if(num==0) { if(stu1.getAge()>stu2.getAge()) return 1; if(stu1.getAge()==stu2.getAge()) return 0; return -1; } */
        return num;
    }
}

第1の方式(要素自体に比較性を持たせるため,これはStudioクラスにComparableインタフェースを実現させた)を用い,クラス内部でcompareToメソッドを上書きしたため,この場合は自然な順序で並べられている.この时、私たちは新しい需要があって、名前によってソートしなければなりません.この时、元のコードを修正することはできません.これはデザインに合わないでしょう.Student自体は比較性を備えているが、私たちが必要としているかどうかは、クラスを新たに定義し、Comparatorインタフェースを実現し、public int comparare(Object o 1,Object o 2)メソッドを上書きする.
public int compare(Object o1,Object o2)
    {
        Student stu1 = (Student)o1;
        Student stu2 = (Student)o2;
        int num= stu1.getName().compareTo(stu2.getName());
        if(num==0)
        {
            return new Integer(stu1.getAge()).compareTo (new Integer(stu2.getAge()));
        }
        return num;
    }

まず年齢(整数)をIntegerクラスに変換し,そのクラスのcompareToメソッドを呼び出して年齢を比較する.返されるのも0、-1、1です.
結果:
lisi02......22
lisi03......20
lisi03......21
lisi06......19