Java知识总结-集合二

来源:互联网 发布:python调用shell脚本 编辑:程序博客网 时间:2024/05/29 10:46


说明:Set集合中TreeSet和HashSet集合的存储原理是重点。


一,集合体系中常见实现类。

List接口常见实现类:

List集合中元素是有序的(即元素存入和去除的顺序是一致的),集合中元素可以重复,该集合体系有索引。

List集合判断元素是否相同,依据元素的equals方法。

实现类一:

ArrayList:

底层的数据结构使用的是数组结构。特点:查询元素块,但是增删稍慢,线程不同步,集合长度可变(默认=初始长度为10)超过容量时集合以50%自动增长;

实现类二:

LinkedList:

底层的数据结构使用的是链表结构。特点:增删速度很快,查询稍慢;

实现类三:

Vector:

底层数据结构为数组结构。特点:线程同步,效率较低,被ArrayLIst替代;


Set接口常见实现类;

Set集合中元素是无序的,元素不能重复。

实现类一:

HashSet:

底层数据结构是哈希表。

HashSet集合实现元素唯一性的方式:当向集合中存入元素时,判断该元素hashcode()方法的值与集合中原有元素的hashcode()值进行比较,如果不同,则认为集合中没有该元素,并向集合中存入该元素。当该元素与集合中原有元素的hashcode()值有相同时,系统会继续调用该元素的equals()方法,如果结构仍为true()则认为集合中已经存在该元素,不再存入。如果equals()结果为false(),则认为是不同的元素,并向集合中添加该元素。

注意:元素进入HashSet集合(即元素地址的哈希值进入HashSet集合),集合根据元素的哈希值排列元素顺序,与元素进入集合的顺序不一定相同。

由于Object类中的equals()方法是根据对象地址来判断结果的,所以在存入集合的元素对象一般会复写 hashcode()方法和equals()方法。

HashSet集合总判断元素是否存在,以及删除等操作都依赖于元素的hashcode()方法和equals()方法。

实现类二;

TreeSet:

底层数据结构式二叉树。

TreeSet集合可以对集合中的元素排序,默认排序方式为自然排序。

TreeSet集合保证集合元素唯一性的依据:当元素的compareTo()方法结果为0时,认为两元素相同。

TreeSet集合排序有两种方式:

第一种方式:让元素自身具备比较性,元素需要实现Comparable接口,覆盖接口的compareTo()方法,这种方式称为元素的自然顺序排序。

第二种方式:当元素本身不具备比较性,或者具备的比较性不是集合所需要的,在初始化集合时,会为集合定义比较器:先自定义一个比较器,将比较器对象做为参数传递黑TreeSet集合的构造函数。


二,HashSet集合示例

例1.当向HashSet集合中添加相同元素时,集合不会存入重复元素;

import java.util.*;public class Test {public static void main(String[] args){//创建集合HashSet hs=new HashSet();//为集合添加元素hs.add("aaa");hs.add("bbb");hs.add("ccc");//当添加元素失败是,add()方法返回false.System.out.println(hs.add("aaa"));System.out.println(hs.add("bbb"));//打印集合System.out.println(hs);}}

运行结果:

falsefalse[aaa, ccc, bbb]

从运行结果可以看出,当为HashSet集合添加已有元素时,添加失败,此时系统自动调用了字符串的hashcode()方法来判断字符串是否相同。


例2:向HashSet集合中添加自定义Student类对象,当Student对象姓名和年龄都相同时默认为同一个对象。

import java.util.*;public class Test {public static void main(String[] args){//创建集合HashSet hs=new HashSet();//为集合添加元素hs.add(new Student("aaa",11));hs.add(new Student("bbb",22));hs.add(new Student("ccc",33));hs.add(new Student("aaa",44));hs.add(new Student("ddd",33));hs.add(new Student("aaa",11));//姓名和年龄与已有元素都相同//打印集合System.out.println(hs);}}class Student{private String name;private int age;Student(String name,int age){this.name=name;this.age=age;}//复写hashcode()方法public int hashcode(){return this.name.hashCode()+this.age*31;}//复写equals()方法public boolean equals(Object obj){if(!(obj instanceof Student))return false;Student stu=(Student)obj;//当两对象姓名年龄都相同时返回truereturn this.name.equals(stu.name)&&this.age==stu.age;} //复写toString()方法public String toString(){return this.name+"--"+this.age;}}

运行结果:

[aaa--44, ccc--33, aaa--11, aaa--11, bbb--22, ddd--33]

通过结果可以看到,只有姓名和年龄都相同时,才被认为是同一元素,


三,TreeSet集合示例

例1:在TreeSet集合中添加字符串,看集合是否为字符串自动排序

import java.util.*;public class Test {public static void main(String[] args){//创建集合TreeSet ts=new TreeSet();//为集合添加元素ts.add("xx");ts.add("aa");ts.add("yy");ts.add("kk");ts.add("cc");ts.add("bb");//打印集合System.out.println(ts);}}

运行结果:

[aa, bb, cc, kk, xx, yy]

从结果可以看出,集合为元素进行了自然排序。


例2:向集合中添加自定义 Student类对象,并按照对象的年龄属性排序,当年龄相同时,按姓名的自然顺序排序。

import java.util.*;public class Test {public static void main(String[] args){//创建集合TreeSet ts=new TreeSet();//为集合添加元素ts.add(new Student("aaa",66));ts.add(new Student("xxx",22));ts.add(new Student("kkk",55));ts.add(new Student("ddd",44));ts.add(new Student("ddd",33));ts.add(new Student("aaa",11));////打印集合System.out.println(ts);}}class Student implements Comparable{ //实现Comparable接口private String name;private int age;Student(String name,int age){this.name=name;this.age=age;}//复写hashcode()方法public int hashcode(){return this.name.hashCode()+this.age*31;}//复写equals()方法public boolean equals(Object obj){if(!(obj instanceof Student))return false;Student stu=(Student)obj;//当两对象姓名年龄都相同时返回truereturn this.name.equals(stu.name)&&this.age==stu.age;} //复写compareTo()方法public int compareTo(Object obj){if(!(obj instanceof Student))throw new RuntimeException("不是Student对象");Student stu=(Student)obj;int num=this.age-stu.age;if(num==0)return this.name.compareTo(stu.name);return num;}//复写toString()方法public String toString(){return this.name+"-"+this.age;}}

运行结果:

[aaa-11, xxx-22, ddd-33, ddd-44, kkk-55, aaa-66]

通过结果可以看到,集合实现了我们自定义的排序方式,将元素按照年龄大小进行排序。


例3:向集合中添加自定义 Student类对象,且不按照Student类自定义的比较方式排序,而是通过传递比较器的方式按照姓名进行排序。当姓名相同时按照年龄的自然顺序排序。

import java.util.*;public class Test {public static void main(String[] args){//创建集合,并传递自定义的比较器TreeSet ts=new TreeSet(new MyCom());//为集合添加元素ts.add(new Student("aaa",66));ts.add(new Student("xxx",22));ts.add(new Student("kkk",55));ts.add(new Student("ddd",44));ts.add(new Student("ddd",33));ts.add(new Student("aaa",11));////打印集合System.out.println(ts);}}//自定义一个按照学生姓名排序的比较器class MyCom implements Comparator<Student>{public int compare(Student s1,Student s2){int num=s1.getName().compareTo(s2.getName());if(num==0)return s1.getAge()-s2.getAge();return num;}}//自定义类并实现Comparable接口,使该类对象具备比较性class Student implements Comparable{private String name;private int age;Student(String name,int age){this.name=name;this.age=age;}public String getName(){return name;}public int getAge(){return age;}//复写hashcode()方法public int hashcode(){return this.name.hashCode()+this.age*31;}//复写equals()方法public boolean equals(Object obj){if(!(obj instanceof Student))return false;Student stu=(Student)obj;//当两对象姓名年龄都相同时返回truereturn this.name.equals(stu.name)&&this.age==stu.age;} //复写compareTo()方法public int compareTo(Object obj){if(!(obj instanceof Student))throw new RuntimeException("不是Student对象");Student stu=(Student)obj;int num=this.age-stu.age;if(num==0)return this.name.compareTo(stu.name);return num;}//复写toString()方法public String toString(){return this.name+"-"+this.age;}}

运行结果:

[aaa-11, aaa-66, ddd-33, ddd-44, kkk-55, xxx-22]
通过结果看出,当为集合传递了比较器后,集合中的元素不再按照元素本身的比较性进行排序,而是按照比较器的方式来进行排序的,所以比较器的优先级要大于元素本身比较性的优先级。



0 0
原创粉丝点击