码迷,mamicode.com
首页 > 编程语言 > 详细

java简单的集合框架(一)

时间:2015-10-15 16:24:19      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:collection   java   vector   集合   元素   

首先让我们看一下简单的集合框架的继承层次

  

                                                                                                                  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等方法时。


本文出自 “没有水勒鱼” 博客,请务必保留此出处http://javaqun.blog.51cto.com/10687700/1703155

java简单的集合框架(一)

标签:collection   java   vector   集合   元素   

原文地址:http://javaqun.blog.51cto.com/10687700/1703155

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!