`

Set接口(Hashset LinkedHashset Treeset)

 
阅读更多

Set接口(HashSet,TreeSet和LinkedHashSet)

Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。
Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不 会接受这两个对象。

事实1:set就是就是相当于Map的kay。

事实2:hashSet是为快速查找而设计的set,存入hashSet的元素必须定义hashCode。而treeSet是保持次序的set,使用treeSet可以从set中提取有序的序列,元素必须实现conparable接口。而

          linkedHashSet具有hashSet的查询速度,且内部是链表结构,因此遍历linkedHashSet时,结果会按照插入顺序显示!

 

HashSet
HashSet有以下特点
 不能保证元素的排列顺序,顺序有可能发生变化
 不是同步的
 集合元素可以是null,但只能放入一个null
当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。

   demo1:

用户自定义类型放进set容器里面,必须要重写equals和hashCode方法,否则会被认为是两个不同的元素。

import java.util.HashSet;
import java.util.Set;

public class overwriteHahcodeAndEquals {
	
	public static void main(String[] args) {
		Set<Object> set = new HashSet<Object>();
		set.add(new Student("lopez",23));
		set.add(new Student("lopez",23));
		set.add(new Student("shengliang",33));
		set.add(new Student("weikun",23));
		set.add(new Student("chencheng",28));
		System.out.println(set);
		//output:[set.Student@1420a8f4, set.Student@9b725c34, set.Student@c2ce75cf, set.Student@8d6b816e]
		//一共4个对象
	}
}

class Student{//内部类
	
	String name;
	int age;
	
	public Student(String name , int age){
		this.name = name;
		this.age = age;
	}
	
	public int hashCode(){//重写hsahCode方法
		return age*name.hashCode();
	}
	
	public boolean equals(Object o){//重写equals方法
		Student s = (Student)o;
		return s.age == this.age && s.name.equals(this.name);
	}
}
   1.分别在hashCode和equals打断点debug,发现在往Set中插入新的对象时,首先会用该对象的hashCode()与已经存在对象的hashCode()做比较,如果相等,那就不能插入,如果不等,才会调用equals()方法,如果equals结果为true,说明已经存在,          就不能再插入,如果为false,可以插入。 
   2.hashSet分别插入字符串对象。
set.add(new String("asd"));
set.add(new String("asd"));
//set只得到一个asd,因为内容相同的String,即使不重写hashCode方法,得到的hashCode都是相同的。
 
   demo2:
package set;

import java.util.HashSet;
import java.util.Set;

public class overwriteHahcodeAndEquals {
	
	public static void main(String[] args) {
		Set<Object> set = new HashSet<Object>();
		set.add(new Student("lopez",23));
		set.add(new Student("lopez",23));
		set.add(new Student("shengliang",33));
		set.add(new Student("weikun",23));
		set.add(new Student("chencheng",28));
		System.out.println(set);
		//output:[set.Student@c2ea3f, set.Student@1d5550d, set.Student@c21495, set.Student@1186fab, set.Student@14b7453]
		//一共5个对象
	}
}

class Student{//内部类
	
	String name;
	int age;
	
	public Student(String name , int age){
		this.name = name;
		this.age = age;
	}
}
   针对demo2,做了个小测试:

 

package set;

import java.util.HashSet;
import java.util.Set;

public class overwriteHahcodeAndEquals {
	
	public static void main(String[] args) {
		Set<Object> set = new HashSet<Object>();
		Student stu = new Student("lopez",23);
		Student stu1 = new Student("lopez",23);
		System.out.println("stu的hashCode值为:" + stu.hashCode());
		System.out.println("stu1的hashCode值为:" + stu1.hashCode());
		System.out.println("stu和stu1 equals比较" + stu.equals(stu1));
		set.add(stu);
		set.add(stu1);
		set.add(new Student("shengliang",33));
		set.add(new Student("weikun",23));
		set.add(new Student("chencheng",28));
		System.out.println(set);
	}
}
class Student{//内部类
	
	String name;
	int age;
	
	public Student(String name , int age){
		this.name = name;
		this.age = age;
	}
	
	/*public int hashCode(){
		return age*name.hashCode();
	}
	
	public boolean equals(Object o){
		Student s = (Student)o;
		return s.age == this.age && s.name.equals(this.name);//int类型的比较和String类型的比较
	}*/
}
  由以下输出可得知:
            //output:stu的hashCode值为:18378667
               //stu1的hashCode值为:21722195
              //stu和stu1 equals比较false
             /[set.Student@c2ea3f, set.Student@1d5550d, set.Student@c21495, set.Student@1186fab, set.Student@14b7453]
  当不重写对象的equals和hashCode方法,则stu和stu1对象比较equals和hashCode得到的值是不相等,所以得到5个对象。

 

 

 

LinkedHashSet
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好(链表结构),但是插入时性能稍微逊色于HashSet,因为插入时linkedHashSet需要维护链表结构。

package set;

import java.util.HashSet;
import java.util.LinkedHashSet;

public class CompareHashSetAndLinkedHashSet {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HashSet set = new LinkedHashSet();
		set.add("lopez1");
		set.add("lopez2");
		set.add("lopez3");
		set.add("lopez4");
		for (Object obj : set) {
			System.out.println(obj.toString());
		}
		//output:
		//lopez1
		//lopez2
		//lopez3
		//lopez4
		
		
		HashSet set1 = new HashSet();
		set1.add("lopez1");
		set1.add("lopez2");
		set1.add("lopez3");
		set1.add("lopez4");
		for (Object obj : set1) {
			System.out.println(obj.toString());
		}
		//lopez1
		//lopez4
		//lopez3
		//lopez2
	}

}

 

 

TreeSet类
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0
自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。
Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。
obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等,如果返回一个正数,则表明obj1大于obj2,如果是 负数,则表明obj1小于obj2。
如果我们将两个对象的equals方法总是返回true,则这两个对象的compareTo方法返回应该返回0
定制排序
自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法

 

按自然顺序demo1:

 

package set;

import java.util.TreeSet;
import java.util.Iterator;

public class TestTreeSet
{
    public static void main(String[] args)
    {
        TreeSet tree = new TreeSet();
        tree.add("China");
        tree.add("America");
        tree.add("England");
        tree.add("Japan");
        tree.add("Chinese");
        tree.add("lapez");
        tree.add("lopez");
        tree.add("lopez1");
        
        Iterator iter = tree.iterator();
        while(iter.hasNext())
        {
            System.out.println(iter.next());
        }
    }
   //output: America
    //China
    //Chinese
    //England
    //Japan
    //lapez
    //lopez
    //lopez1

}

   

   定制排序

package set;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class TestTreeSet {

    /** *//**
     * @param args
     */
    public static void main(String[] args) {

        MyComparator<String> myComparator = new MyComparator<String>();

        // /////////////////////不添加自定义排序
        TreeSet<String> treeSet1 = new TreeSet<String>();
        treeSet1.add("c");
        treeSet1.add("a");
        treeSet1.add("b");

        Iterator<String> iterator1 = treeSet1.iterator();
        while (iterator1.hasNext()) {
            System.out.println(iterator1.next());
        }

        // /////////////////////添加自定义排序
        TreeSet<String> treeSet2 = new TreeSet<String>(myComparator);
        treeSet2.add("c");
        treeSet2.add("a");
        treeSet2.add("b");

        Iterator<String> iterator2 = treeSet2.iterator();
        while (iterator2.hasNext()) {
            System.out.println(iterator2.next());
        }
    }

}

class MyComparator<T> implements Comparator<T> {

    public int compare(T arg0, T arg1) {
        if (arg0.equals(arg1)) {
            return 0;
        }
        return ((Comparable<T>) arg0).compareTo(arg1) * -1;
    }

}

 

 

 

分享到:
评论

相关推荐

    HashSet,TreeSet和LinkedHashSet的区别1

    本文主要探讨了三种基于Set接口的实现类:HashSet、LinkedHashSet和TreeSet,它们各自有不同的特性和使用场景。 首先,HashSet是最基础的Set实现,它不保证元素的特定顺序,也不保证在多次操作后保持元素的顺序不变...

    Java—Set集合详解(HashSet/LinkedHashSet/TreeSet/EnumSet)

    本文将深入探讨Java中四个主要的Set实现类:HashSet、LinkedHashSet、TreeSet以及EnumSet。 首先,Set集合的核心特性是不存储重复元素。在尝试通过`add()`方法添加相同元素时,如果集合中已经存在该元素,`add()`...

    ThinkinginJava之Set接口、HashSet源码学习.pdf

    HashSet类实现了Set接口,其内部基于HashMap来存储和管理元素。这意味着HashSet的性能和特性与HashMap紧密相关。由于HashMap使用哈希表结构,HashSet能够快速地插入、查找和删除元素,时间复杂度通常为O(1)。 ...

    java中set接口使用方法详解

    Set接口的实现类主要有HashSet、TreeSet和LinkedHashSet,它们各自有不同的特性和使用场景。 1. **HashSet** HashSet是最基本的Set实现类,它的内部基于HashMap实现。这意味着它的元素存储是无序的,且通过哈希...

    java8源码-JavaRobot:Java学习笔记,JavaLearningNote

    java8 源码 学习笔记(持续更新中) 所有文章均同步发布到微信公众号...LinkedHashSet TreeSet HashSet Concurrent源码系列 待完善 JVM(Java虚拟机) 类加载 垃圾回收算法 JavaConcurrent(Java并发系列) 【Java并发系列】

    Java软件开发实战 Java基础与案例开发详解 11-3 Set接口实现类 共19页.pdf

    本文将详细介绍`Set`接口及其三种主要实现类:`HashSet`、`LinkedHashSet`和`TreeSet`。 ### 11.3.1 实现类HashSet `HashSet`类是基于哈希表的`Set`接口实现。它不保证集合中元素的顺序,并且不允许有重复元素。`...

    Java 基础核心总结 +经典算法大全.rar

    AbstractSet 抽象类SortedSet 接口HashSet LinkedHashSet TreeSet List 接口 AbstractList 和 AbstractSequentialList Vector Stack ArrayList LinkedList Queue接口Deque 接口 AbstractQueue 抽象类LinkedList ...

    set接口经常用的hashCode和equals方法详解

    根据存储和检索元素的方式不同,`Set`接口有多种实现类,如`HashSet`、`LinkedHashSet`和`TreeSet`等。其中,`HashSet`使用哈希表实现,`LinkedHashSet`则在此基础上保持了元素的插入顺序,而`TreeSet`则是基于红黑...

    Java集合框架Set接口.pdf

    HashSet是Set接口的最常见实现类,它的内部基于哈希表(HashMap)来存储元素。由于哈希表的特性,HashSet提供了快速的插入、删除和查找操作,时间复杂度为O(1)。这意味着在理想情况下,这些操作几乎瞬间完成。然而,...

    JavaSE专题-Set集合.doc

    Set集合是JavaSE中的一种重要数据结构,主要包括HashSet、TreeSet和LinkedHashSet三个子类。下面我们将对Set集合的原理、特点、使用场景等进行详细的探索和分析。 HashSet HashSet是Set集合中的一种重要实现类,...

    java 运用集的相关类(Set)

    Java提供了多种Set接口的实现,如HashSet、TreeSet和LinkedHashSet。 1. HashSet:这是最常用的Set实现,它不保证元素的顺序,允许使用null值,但不允许元素重复。HashSet内部使用哈希表来存储元素,因此添加、删除...

    JAVA容器讲解.pdf

    Java容器讲解PPT,Collection Map(HashMap TreeMap LinkedHashMap) List (ArrayList LinkedList Vector) Set (HashSet TreeSet LinkedHashSet)

    Java集合面试题汇总.pdf

    Set接口代表不允许有重复元素的集合,如HashSet、TreeSet和LinkedHashSet。List接口则表示有序的、允许重复元素的集合,如ArrayList、LinkedList和Vector。Map接口则不同于Collection,它是键值对存储的接口,常见的...

    Java 72 道面试题及答案.docx

    Set 接口的实现类主要有:HashSet、TreeSet、LinkedHashSet 等。List 接口的实现类主要有:ArrayList、LinkedList、Stack 以及 Vector 等。 List、Set、Map 三者的区别是:List 是一个有序容器,元素可以重复,可以...

    Java面试题及答案-共72道.docx

    Set 接口的实现类主要有 HashSet、TreeSet、LinkedHashSet 等,分别基于 HashMap、红黑树和链表结构实现的。Map 接口的实现类主要有 HashMap、TreeMap、Hashtable 等,分别基于数组+链表、红黑树和数组+链表结构实现...

    Collection,List,Set和_Map用法和区别

    Set 的实现类有 HashSet、LinkedHashSet 和 TreeSet。HashSet 是一种哈希集,元素的顺序是随机的,LinkedHashSet 是一种链表集,元素的顺序是按照添加顺序的,TreeSet 是一种树形集,元素的顺序是按照比较器的顺序的...

    Set用法及与List的区别

    在Set接口下有许多实现类,如HashSet、TreeSet和LinkedHashSet等。我们以`HashSetDemo.java`为例,探讨HashSet的使用方法。 `HashSet`是Java中最常用的Set实现类,它基于哈希表(HashMap)实现,提供了快速的插入、...

    java集合总结.pdf

    Set接口的实现类包括HashSet、LinkedHashSet、TreeSet等。 HashSet是Set接口的哈希表实现,不保证set的迭代顺序;特别是它不保证该顺序恒久不变。 LinkedHashSet是Set接口的哈希表和链接列表实现,具有可预知迭代...

Global site tag (gtag.js) - Google Analytics