Java类集框架——Set接口和子接口SortedSet以及SortedSet接口的子类TreeSet之间的联系和使用、排序设置重复元素的说明

来源:互联网 发布:nvh有限元软件 编辑:程序博客网 时间:2024/05/01 07:54

学习目标:

掌握Set接口与Collection接口的关系。
掌握Set接口的常用子类:TreeSet、HashSet。
掌握TreeSet的排序原理。
掌握Set接口中重复元素的定义。
掌握SortedSet接口与Set接口的关系。
掌握SortedSet接口常用的操作方法。

Set接口的定义:

Set接口也是Collection接口中的子接口,但是与Collection或List接口不同的是,Set接口中不能加入重复的元素。
Set接口的定义:public interface Set<E> extends Collection<E>
Set接口的主要方法与Collection是一致的。
Set接口的实例无法像List接口那样进行双向输出。
Set接口的常用子类:
     散列存放:HashSet
     有序存放:TreeSet

Collection不能进行双向输出,Set接口与Collection接口定义一致,所以本身也不能双向输出。
HashSet:使用散列的方式存放,本身没有顺序。
import java.util.HashSet ;import java.util.Set ;public class HashSetDemo01{public static void main(String args[]){Set<String> allSet = new HashSet<String>() ;allSet.add("A") ;// 增加内容allSet.add("B") ;// 增加内容allSet.add("C") ;// 增加内容allSet.add("C") ;// 重复内容allSet.add("C") ;// 重复内容allSet.add("D") ;// 增加内容allSet.add("E") ;// 增加内容System.out.println(allSet) ;}};

是无序排列的,而List接口的内容插入顺序就是其保存顺序。
如果现在希望所有的内容可以自动进行排序的操作,则可以使用Set中的第二个子类TreeSet。
import java.util.HashSet ;import java.util.Set ;import java.util.TreeSet;public class TreeSetDemo01{public static void main(String args[]){Set<String> allSet = new TreeSet<String>() ;allSet.add("A") ;// 增加内容allSet.add("B") ;// 增加内容allSet.add("C") ;// 增加内容allSet.add("C") ;// 重复内容allSet.add("C") ;// 重复内容allSet.add("D") ;// 增加内容allSet.add("E") ;// 增加内容System.out.println(allSet) ;}};

TreeSet的子类是可以自动进行排序的。

TreeSet类的内容是可以排序的,如果任意给出一个自定义的类,观察能否进行排序操作。
import java.util.Set ;import java.util.TreeSet ;class Person{private String name ;private int age ;public Person(String name,int age){this.name = name ;this.age = age ;}public String gtoString(){return "姓名:" + this.name + ";年龄:" + this.age ;}};public class TreeSetDemo02{public static void main(String args[]){Set<Person> allSet = new TreeSet<Person>() ;allSet.add(new Person("张三",30)) ;allSet.add(new Person("李四",31)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("赵六",33)) ;allSet.add(new Person("孙七",33)) ;System.out.println(allSet) ;}};
执行时出现了错误,如下所示:

Comparable之前曾经讲解过主要是进行排序的操作接口,一个对象数组要想排序,则依靠Comparable接口完成。那么对于TreeSet也一样,如果要想使用TreeSet进行排序的操作,则对象所在的类也必须实现Comparable接口。
import java.util.Set ;import java.util.TreeSet ;class Person implements Comparable<Person>{private String name ;private int age ;public Person(String name,int age){this.name = name ;this.age = age ;}public String toString(){return "姓名:" + this.name + ";年龄:" + this.age ;}public int compareTo(Person per){if(this.age>per.age){return 1 ;}else if(this.age<per.age){return -1 ;}else{return 0 ;}}};public class TreeSetDemo03{public static void main(String args[]){Set<Person> allSet = new TreeSet<Person>() ;allSet.add(new Person("张三",30)) ;allSet.add(new Person("李四",31)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",33)) ;allSet.add(new Person("赵六",34)) ;allSet.add(new Person("孙七",34)) ;System.out.println(allSet) ;}};

发现此时去掉了重复元素,但是依靠的是Comparable接口完成的。孙七没有加入进来,因为两个的年龄是完全一样的,而此时的Comparable接口比较的只是年龄,所以为了保证正确,所有的属性都应该进行比较:
import java.util.Set ;import java.util.TreeSet ;class Person implements Comparable<Person>{private String name ;private int age ;public Person(String name,int age){this.name = name ;this.age = age ;}public String toString(){return "姓名:" + this.name + ";年龄:" + this.age ;}public int compareTo(Person per){if(this.age>per.age){return 1 ;}else if(this.age<per.age){return -1 ;}else{return this.name.compareTo(per.name) ;// 调用String中的compareTo()方法}}};public class TreeSetDemo04{public static void main(String args[]){Set<Person> allSet = new TreeSet<Person>() ;allSet.add(new Person("张三",30)) ;allSet.add(new Person("李四",31)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("赵六",33)) ;allSet.add(new Person("孙七",33)) ;System.out.println(allSet) ;}};

此时去掉的重复元素并不是真正意义上的重复元素的取消。
import java.util.Set ;import java.util.HashSet ;class Person{private String name ;private int age ;public Person(String name,int age){this.name = name ;this.age = age ;}public String toString(){return "姓名:" + this.name + ";年龄:" + this.age ;}};public class RepeatDemo01{public static void main(String args[]){Set<Person> allSet = new HashSet<Person>() ;allSet.add(new Person("张三",30)) ;allSet.add(new Person("李四",31)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("赵六",33)) ;allSet.add(new Person("孙七",33)) ;System.out.println(allSet) ;}};

此时,并没有去除重复的元素,那么重复的元素该如何取消呢?
如果想取消重复的元素,则需要Object类中的两个方法帮助:
hashCode():表示一个唯一的编码,一般通过计算表示。
equals():进行对象的比较操作。
import java.util.Set ;import java.util.HashSet ;class Person{private String name ;private int age ;public Person(String name,int age){this.name = name ;this.age = age ;}public boolean equals(Object obj){// 覆写equals,完成对象比较if(this==obj){return true ;}if(!(obj instanceof Person)){return false ;}Person p = (Person)obj ;// 向下转型if(this.name.equals(p.name)&&this.age==p.age){return true ;}else{return false ;}}public int hashCode(){return this.name.hashCode() * this.age; // 定义一个公式}public String toString(){return "姓名:" + this.name + ";年龄:" + this.age ;}};public class RepeatDemo02{public static void main(String args[]){Set<Person> allSet = new HashSet<Person>() ;allSet.add(new Person("张三",30)) ;allSet.add(new Person("李四",31)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("王五",32)) ;allSet.add(new Person("赵六",33)) ;allSet.add(new Person("孙七",33)) ;System.out.println(allSet) ;}};

如果要想使用Set,则就必须注意以上的两个问题。

SortedSet接口中定义的方法

1、public Comparator<? super E> comparator()  普通 返回与排序有关联的比较器。
2、public E first()  普通 返回集合中的第一个元素。
3、public SortedSet<E> headSet(E toElement)普通  返回从开始到指定元素的集合。
4、public E last()   普通 返回最后一个元素。
5、public SortedSet<E> subSet(E fromElement, E toElement)普通  返回指定对象间的元素。
6、public SortedSet<E> tailSet(E fromElement) 普通  从指定元素到最后。
import java.util.SortedSet ;import java.util.TreeSet ;public class TreeSetDemo05{public static void main(String args[]){SortedSet<String> allSet = new TreeSet<String>() ;// allSet.add("A") ;// 增加内容allSet.add("B") ;// 增加内容allSet.add("C") ;// 增加内容allSet.add("C") ;// 增加内容allSet.add("C") ;// 增加内容allSet.add("D") ;// 增加内容allSet.add("E") ;// 增加内容System.out.println("第一个元素:" + allSet.first()) ;System.out.println("最后一个元素:" + allSet.last()) ;System.out.println("headSet元素:" + allSet.headSet("C")) ;System.out.println("tailSet元素:" + allSet.tailSet("C")) ;System.out.println("subSet元素:" + allSet.subSet("B","D")) ;}};

总结:
1、之前曾经遇到:一个好的类应该覆写Object类中的equals()、hashCode()、toString()三个方法,实际上String类中已经全部覆写完成了。
2、Set接口依靠hashCode()和equals()完成重复元素的判断,关于这一点在以后的Map接口中也有体现。
3、TreeSet依靠Comparable接口完成排序操作。
4、只要看见了以Sorted开头的接口基本上都是表示可以排序的接口。


0 0
原创粉丝点击