您的位置:首页 > 编程语言 > Java开发

java简单的集合框架(一)

2015-10-15 13:55 561 查看
首先让我们看一下简单的集合框架的继承层次

collection

list(有序的容器 元素可以重复) Queue(队列)
set(无序的容器就是元素不可重复)

linkedList ArrayList Vector Deque PriorityQueue EnumSet
SortedSet HashSet

TreeSet

Collection(接口)是集合容器中非映射关系的容器类的根类。其中list和set 接口是最常用的接口。其中list有序指的遍历的结果与插入的顺序相同,set无序指的是插入的顺序与遍历的顺序不一定相同(因为在插入的时候,它会按照元素中ComparaTo()方法去完成排序,同时容器中的元素会按照某种关系将元素映射到一个HashMap中,这样可以实现快速遍历。)

1.ArrayList和Vector 的底层实现都是数组,可以通过下标索引来访问,这样可以提高查询效率,但是增删效率低。同时ArrayList的默认容量为10个元素,而且它的扩充容量为原来容量的(1.5倍+1)程序中的源代码为 int newCapacity = (oldCapacity * 3)/2 + 1;Vector的底层也为数组。它的默认容量也为10,但是在自动增长的时候,如果在构造函数中指定了增长的容量,则在增长的时候,它的容量会变成原来数组的容量+增长量,如果没有指定增长量,则会按照系统规定的2倍进行。所以在开发的过程当中,如果我们能估计容器中大约能盛放多少元素,我们应该在初始化的时候给他一个容量的大小。同时ArrayList是线程不安全的,Vector是线程安全的,但是ArrayList的性能比Vector的性能高。

2.LinkedList的底层实现为单链表,它查询效率低,但是增删效率高。

3.一般的遍历方式为用Iterator这个迭代器进行,这样遍历的时候效率是高的因为这样和遍历数组差不多,它是通过索引来实现的。

4.容器一般用来盛放对象的,在判断一个容器中是否包含某个对象以及在通过Equals()方法比较两个容器是否相同时,这时是根据容器中的对象元素来比较的。也就是放入容器中的对象必须实现equals()方法。

这是存放到容器中的对象定义,并且重写了Equals()方法。

public class Pet {

private String name;

private String color;

private int age;

public Pet(String name, String color, int age) {

this.name = name;

this.color = color;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getColor() {

return color;

}

public void setColor(String color) {

this.color = color;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

@Override

public String toString() {

// TODO Auto-generated method stub

return "姓名:"+getName()+"颜色:"+getColor()+"年龄:"+getAge();

}

@Override

public boolean equals(Object obj) {

// TODO Auto-generated method stub

if(this==obj)

return true;

if((!(obj instanceof Pet)))

return false;

Pet pet=(Pet)obj;

if(this.age==pet.getAge()&&this.color.equals(pet.getColor())

&&this.name.equals(pet.getName()))

return true;

return false;

}

}

在主函数中的代码:

public class TestVector {

public static void main(String[] args) {

Pet pet0=new Pet("小白","红色",12);

Pet pet1=new Pet("小白","红色",13);

Pet pet2=new Pet("小白","红色",14);

Pet pet3=new Pet("小白","红色",16);

Pet pet4=new Pet("小白","红色",12);

ArrayList<Pet>arrayList=new ArrayList<Pet>();

arrayList.add(pet1);

arrayList.add(pet2);

arrayList.add(pet3);

arrayList.add(pet4);

boolean flag;

flag=arrayList.contains(pet0);

System.out.println("flag="+flag); //如果Pet重写了Equals()方法这时返回的是true,如果没有则会为false.因为Pet没有重写Equals()方法则会调用Object的Equals()方法。因为在比较的时候

//如果Pet没有重写Equals()则比较的是存放在数组中的地址,如果实现了则比较的是数组中元素的内容。

}

3.总结一下TreeSet 集合。

放入Treeset中的元素对象要么实现Comparable接口,要么不实现Comparable接口,在生成Treeset 容器的时候,在构造器中加入比较器。比较器相当于裁判,来实现排序作用的。TreeSet集合中元素的排序,

判断是否包含某个元素,等都是通过比较器来实现的。它的底层实现为二叉树。

下面的例子为插入到树结构的对象,是按照薪资大小,如果薪资大小一样则是按工龄大小来实现的排序。

public class Employee1 implements Comparable<Employee1>{

private int workAge;

private double salary;

public Employee1(int workAge, double salary) {

super();

this.workAge = workAge;

this.salary = salary;

}

public int getWorkAge() {

return workAge;

}

public void setWorkAge(int workAge) {

this.workAge = workAge;

}

public double getSalary() {

return salary;

}

public void setSalary(double salary) {

this.salary = salary;

}

@Override

public String toString() {

return "Employee [workAge=" + workAge + ", salary=" + salary + "]";

}

@Override

public int compareTo(Employee1 o) {

// TODO Auto-generated method stub

if(this.salary==o.getSalary()){

return

this.getWorkAge()-o.getWorkAge();

}else{

if(this.getSalary()>o.getSalary()){

return 1;

}else {

return -1;

}

}

}

}

public class TestTreeSet {

public static void main(String[] args) {

TreeSet employeeSet=new TreeSet();

employeeSet.add(new Employee1(34,20000.0));

employeeSet.add(new Employee1(35,20000.0));

employeeSet.add(new Employee1(35, 20000.2));

employeeSet.add(new Employee1(35,30000.0));

Iterator iterator=employeeSet.iterator();

Object obj=null;

while(iterator.hasNext()){

obj=iterator.next();

System.out.println(obj);

}

}

}

运行的结果为:

Employee [workAge=34, salary=20000.0]

Employee [workAge=35, salary=20000.0]

Employee [workAge=35, salary=20000.2]

Employee [workAge=35, salary=30000.0]

4.总结一下HashSet集合

HashSet的底层实现为HashMap,也就是说,放入集合中的元素,作为HashMap的键。由于键是唯一的,所以对应的HashSet集合也是唯一的,并且,HashMap的键值允许为空,所以集合中可以放入空元素。放入HashSet集合中的对象元素

一般重写hashCode()方法和equals()方法。重写hashCode()方法,比如在Student 类中,我们的hashCode()重写为

int hashCode()

{

return age;

}

这也就是说,年龄相同的对象元素放在同一个通中。在遍历输出的时候,在同一个桶中的元素会顺序遍历出来。就是年龄相同的对象顺序遍历出来。

public class Student {

private String name;

private int age;

public Student(String name, int age) {

super();

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

@Override

public int hashCode() {

return age;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Student other = (Student) obj;

if (age != other.age)

return false;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}

@Override

public String toString() {

return "Student [name=" + name + ", age=" + age + "]";

}

}

public class testHashSet {

public static void main(String[] args) {

Student s1=new Student("徐才厚",18);

Student s2=new Student("徐财厚", 18);

Student s3=new Student("旺财", 18);

Student s4=new Student("徐才厚",19);

Student s5=new Student("徐财厚", 19);

Student s6=new Student("旺财", 19);

Student s7=new Student("徐才厚",20);

Student s8=new Student("徐财厚", 20);

Student s9=new Student("旺财", 20);

Student s0=null;

HashSet<Student>hashset=new HashSet<Student>();

hashset.add(s1);

hashset.add(s2);

hashset.add(s3);

hashset.add(s4);

hashset.add(s5);

hashset.add(s6);

hashset.add(s7);

hashset.add(s8);

hashset.add(s9);

hashset.add(s0);

Iterator<Student> set=hashset.iterator();

while(set.hasNext()){

Student st=set.next();

System.out.println(st);

}

}

}

输出结果:

null

Student [name=旺财, age=19]

Student [name=徐财厚, age=19]

Student [name=徐才厚, age=19]

Student [name=旺财, age=18]

Student [name=徐财厚, age=18]

Student [name=徐才厚, age=18]

Student [name=旺财, age=20]

Student [name=徐财厚, age=20]

Student [name=徐才厚, age=20]

总结: equals方法和hashcode方法

在容器中如果调用remove,contains等方法时,这会设计到对象类型的equals()和hashcode()方法,对于自定义的类型,需要重写equals()方法和hashcode()方法,以实现自定的对象相等的规则。在Java中,俩个内容相同的对象应该具有相同的hashcode.所以如果两个对象的hashcode不相等,则两个对象的内容肯定不相等,这样就不用一个一个去比较属性值了,从而提高对象的比较速度。

有可能重写equals()方法和hashcode()方法的情况

1.要将我们自定义的对象放入HashSet中处理

2,。要将我们自定义的对象作为hashMap 的key处理。

3.放入Collection容器中的自定义对象后,可能会调用remove,contains等方法时。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: