JAVA SE回顾---集合(1)

来源:互联网 发布:mac照片幻灯片 编辑:程序博客网 时间:2024/05/20 10:23

集合的介绍:

  集合也是一种容器,与数组不同的是它的长度是可变的,只能存储引用类型。


集合的体系介绍:


Collection是Set和List接口的父接口。它的所有功能子类都可以使用。ArrayList,LinkedList,Vector是List接口的几个实现类。HashSet和LinkedHashSet是Set的两个实现类。


Collection接口的重要方法:

boolean add(): 在集合中添加元素,返回值为boolean类型,添加成功返回true,失败返回false

void clear(): 移除此集合中所有元素,不删除集合

boolean contains(Object o): 检测集合中是否包含某个元素

boolean remove(Object o): 从集合中删除指定元素

boolean removeAll(Collection<?>c):删除集合中,包含另一个集合的元素

int size(): 返回集合的元素数

Object[] toArray():用于返回一个集合中所有元素的数组

Iterator<E> iterator(): 返回在这个Collection的元素上进行迭代的迭代器。

使用Iterator遍历的代码实现:

//获取迭代器Iterator<String> it = coll.iterator();//迭代是反复进行,且次数不确定则应该用whilewhile(it.hasNext()){String s = it.next();System.out.println(s);}//for循环相较于while更节约内存,while循环的迭代器是在main中建立的,main方法不结束迭代器就不会释放内存,而for//循环的迭代器是在for循环内部建立的,只要for循环结束迭代器也就结束for (Iterator<String> it1 = coll.iterator(); it1.hasNext(); ) {System.out.println(it1.next());}


迭代器的实现原理:

当使用iterator()方法创建迭代器时就在集合的元素前创建一个指针(即索引-1处),使用hasNext()方法就是判断下一位是否有元素,如果有则返回true,next()方法就是将指针向下移动一位并返回该元素。


List接口的特点和特有方法:

它是一个有顺序的集合,可以按照存入的顺序来取出,因此它的元素师有顺序的。它可以存储重复的元素。List集合因为拥有索引可以使用索引进行迭代。


void add(int index,E element):在集合中指定位置添加元素

E get(int index): 返回集合中指定位置的元素

E remove(int index):删除集合中指定位置的元素,若有多个仅删除第一个

boolean remove(Object o): 删除集合中指定元素,并返回是否删除成功

E set(int index,E element):替换集合中指定位置的元素


List集合存储数据的结构:

堆栈:

   先进后出。先存进去的元素要最后才能取出。类似于枪械弹夹。

   栈的入口和出口都是最顶端的位置。

   压栈:就是存储元素,把元素存储到栈最顶端,先存进去的元素在往栈底移动一位。

   弹栈:取元素,最后存的元素取出,其他元素往栈顶移动一位。

队列:

  先进先出。先存储的元素先取出。类似于排队。

  队列的入口出口分别在两侧。存储元素的时候已有的都会向出口处移动一位。

数组:

  查询快。因为每个元素都有索引,通过索引可以快速定位元素。

  增删慢。因为数组长度是不可变的,因此增删一个元素都要重现创建一个数组进行操作。

链表:就是把多个节点连接起来。节点由数据域(存储的数值)和指针域(存储的地址地址)组成

  多个节点之间,通过地址连接起来。

  增删快。只需要修改下一个元素的链接地址就可以。

  查询慢。需要从节点依次往后一一查找。

二叉树:

  在存储第二个元素时会与第一个元素做减法,为正则在右边,负则在左边,为0则不存储。取出的顺序从左往右依次取出。


ArrayList:

  该集合的底层是数组,因此具有查询快增删慢的特点。

ArrayList判断几何元素是否重复的原理:

ArrayList的contains方法使用调用方法时,传入的元素的equals方法依次与集合中的旧元素所比较,从而根据返回的布尔值判断是否有重复元素。此时,当ArrayList存放自定义类型时,由于自定义类型在未重写equals方法前,判断是否重复的依据是地址值,所以如果想根据内容判断是否为重复元素,需要重写元素的equals方法。



LinkedList:

  该集合的底层是链表,因此具有查询慢增删快的特点。



Vector:

  该数组的底层也是数组。它有一个枚举Enumeration,它其实就是早期的迭代器。Enumeration接口的功能与 Iterator接口的功能是类似的。Vector集合已被ArrayList替代。枚举Enumeration已被迭代器Iterator替代。


Set接口的特点:

  Set集合存放的元素是无序的而且不重复的。


HashSet:此类实现自Set接口,底层是哈希表。这个集合不能保证迭代顺序与存入的顺序相同。它保证寸出数据的唯一性依赖于hashCode()和equals()方法。


HashSet存储的数据结构(哈希表):

   哈希表底层使用的也是数组机制,数组中也存放对象,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。

当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

   保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。(重写可以在eclipse中使用shift+alt+s自动生成)在HashSet中存储已有的元素时不需要重写hashCode()和equals()方法,因为在每个类中已经重写过了。


LinkedHashSet集合的特点:它是链表和哈希表组成的一个数据存储结构。它可以保证元素的存取顺序一致。


TreeSet:

  底层是二叉树,是一个有序的集合。当存储得是字符串时会根据字典顺序排。如果是存储自定义对象,则需要实现comparable接口,并实现compareTo方法。一般不需要排序的就用HashSet来存,TreeSet要排序,运行起来会较慢。


代码实现:

public  class Student implements Comparable<Student>{private String name;private int age;public Student(String name, int age) {super();this.name = name;this.age = age;}public Student() {super();// TODO Auto-generated constructor stub}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;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}//实现Comparable接口的同时必须实现这个比较法@Overridepublic int compareTo(Student s) {//就是写的是元素的比较规则,由你自己去动手写出//按照学生的年龄进行排序int num = this.age - s.age;//判断年龄是否相同,如果相同比较姓名/** * 写这个比较规则的时候注意两点: * 1.他有主要条件,先按照主要条件进行排序 * 2.如果主要条件相同,就需要你自己分析出来他的次要条件,再去按照次要条件进行比较 *///(a<b)?a:b"它是这样执行的:  如果a<b为真,则表达式取a值,否则取b值//先判断年龄是否相同,如果两个人年龄相同则进行姓名比较。int num2 = num==0?this.name.compareTo(s.name):num;return num2;}
使用匿名内部类来进行改进:

TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {int num = s1.getAge() - s2.getAge();int num2 = num==0?s1.getName().compareTo(s2.getName()):num;return num2;}});