java容器--Set集合中的体系结构分析(二)
2015-10-21 16:06
549 查看
Set集合:
元素存储无序(不按照存入的顺序存储)。且不能重复
|--HashSet: 底层数据结构是hash表。|--TreeSet: 存入数据按照自然顺序排序
Set方法和Collection提供的方法一致。
HashSet提供的方法:
HashSet是如何保证存储数据的唯一性呢?通过元素的两个方法来完成的,分别是hashCode和equals方法。
1、HashSet在存储数据时,内部首先调用hashCode方法,如果hashCode一致,在调用equals方法
2、如果hashCode不一致,那么就将数据存储到hashSet集合中。
import java.util.*;
public class SetDemo{
public static void main(String args[]){
HashSet hs = new HashSet();
hs.add(new Person("lzl",18));
hs.add(new Person("lzl",18));
hs.add(new Person("hhh",18));
hs.add(new Person("lzl",18));
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;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public int getAge(){
return this.age;
}
public String getName(){
return this.name;
}
//覆写hashCode()方法,保证hashCode具有唯一性
public int hashCode(){
System.out.println("hashCode---"+this.name.hashCode()*age);
return this.name.hashCode()*age;
}
//因为要比较的是Person类中的name和age值,所以重写Object类的equals方法,
public boolean equals(Object obj){
//如果传入的对象不是Person类,直接返回false
if(!(obj instanceof Person))
return false;
//否则强转成Person类
Person p = (Person)obj;
//返回name和age的比较值。
return this.name.equals(p.getName()) && this.age == p.getAge();
}
}
TreeSet提供的方法
TreeSet集合1、存储的数据自身具有比较性。
2、保证数据唯一性的依据是CompareTo()方法return 0。
使用该集合的对象要实现Comparable接口,覆写CompareTo()方法。
如果CompareTo()return 0表示对象相同。(如例1)
3、如果对象不具有比较器,或者该对象的比较器不是你所想要的。
那么可以通过定义实现比较接口,来实现自定义的比较器(看例2)。
例1:定义一个学生类,存入姓名的年龄,要求按照年龄进行排序。
import java.util.*; public class SetDemo{ public static void main(String args[]){ TreeSet ts = new TreeSet(); ts.add(new Student("lzl",18)); ts.add(new Student("lzl",19)); ts.add(new Student("lzl",10)); ts.add(new Student("lzl",20)); ts.add(new Student("lml",20)); ts.add(new Student("lzl",20)); Iterator it = ts.iterator(); while(it.hasNext()){ Student s = (Student)it.next(); sop(s.getName()+"------"+s.getAge()); } } public static void sop(Object obj){ System.out.println(obj); } } /** 因为要将学生类按照年龄来排序,所以要实现Comparable接口,并 覆写compareTo(Object obj)方法 */ class Student implements Comparable { private String name ; private int age; public Student(){ } public Student(String name,int age){ this.name = name; this.age = age; } public int getAge(){ return this.age; } public String getName(){ return this.name; } /** return:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。 */ public int compareTo(Object obj){ if(!(obj instanceof Student)) throw new RuntimeException("不是学生类"); Student s = (Student)obj; if(this.age > s.getAge()) return 1; if(this.age == s.getAge()){ //年龄如果相同,比较姓名是否相同 return this.name.compareTo(s.getName()); } return -1; } }例2:改变学生类的需求,要求让存储的学生类按照姓名的字母排序。
import java.util.*; public class TreeSetDemo{ public static void main(String args[]){ TreeSet ts = new TreeSet(new myCopara()); ts.add(new Student("lzl",18)); ts.add(new Student("lzl",19)); ts.add(new Student("lzl",10)); ts.add(new Student("lzl",12)); ts.add(new Student("lml",20)); ts.add(new Student("lzl",20)); ts.add(new Student("xy",20)); ts.add(new Student("as",100)); Iterator it = ts.iterator(); while(it.hasNext()){ Student s = (Student)it.next(); sop(s.getName()+"------"+s.getAge()); } } public static void sop(Object obj){ System.out.println(obj); } } /** 实现Comparator接口,并覆写int compare(T o1, T o2) */ class myCopara implements Comparator{ public int compare(Object o1,Object o2){ if(!(o1 instanceof Student) || !(o2 instanceof Student)) throw new RuntimeException("不是学生类型"); Student s1 = (Student)o1; Student s2 = (Student)o2; int num = s1.getName().compareTo(s2.getName()); if(num == 0){ return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); } return num; } } class Student { private String name ; private int age; public Student(){ } public Student(String name,int age){ this.name = name; this.age = age; } public int getAge(){ return this.age; } public String getName(){ return this.name; } }练习:定义一堆字符串,要求按照字符串的长度大小来排序,如果字符串长度相同,那么按照字符串的字母顺序排序。
import java.util.*; public class TreeSetDemo{ public static void main(String args[]){ TreeSet ts = new TreeSet(new myCopara()); ts.add("abc"); ts.add("abcd"); ts.add("abcde"); ts.add("abce"); ts.add("fffff"); ts.add("fffff"); // ts.add(2); Iterator it = ts.iterator(); while(it.hasNext()){ String s = (String)it.next(); sop(s); } } public static void sop(Object obj){ System.out.println(obj); } } /** 实现Comparator接口,并覆写int compare(T o1, T o2) */ class myCopara implements Comparator{ public int compare(Object o1,Object o2){ if(!(o1 instanceof String) || !(o2 instanceof String)) throw new RuntimeException("不是字符串类型"); String s1 = (String)o1; String s2 = (String)o2; int size1 = s1.length(); int size2 = s2.length(); int num = new Integer(size1).compareTo(new Integer(size2)); //如果长度相同,那么按照字符串的字母顺序排列 if(num == 0){ //System.out.println(s1+"----"+s2); return s1.compareTo(s2); } return num; } }
相关文章推荐
- set 命令特殊用法
- You must SET PASSWORD before executing this statement的解决方法
- 批处理 Set 命令详解 让你理解set命令第1/2页
- ASP中set与dim的区别(自己的理解)
- 深入C#中get与set的详解
- sql Set IDENTITY_INSERT的用法
- set_include_path在win和linux下的区别
- jquery中常用的SET和GET
- 大家注意vector, list, set, map成员函数erase
- 基于SQL中SET与SELECT赋值的区别详解
- mysql之set与enum的介绍
- php set_magic_quotes_runtime() 函数过时解决方法
- MySQL的FIND_IN_SET函数使用方法分享
- .net get set用法小结第1/3页
- mysqli_set_charset和SET NAMES使用抉择及优劣分析
- asp.net get set用法第1/2页
- java比较器comparator使用示例分享
- Java 中Comparable和Comparator区别比较
- Java集合类中文介绍
- python线程join方法与seDaemon方法