1.1、单列集合
注:集合中的元素都是Object类型的,没加泛型注意向下转型。
1、List
凡是可以操作角标的方法都是List体系特有的方法,下面是它的常用方法:
- void add(index,element)://在指定位置添加元素。
- boolean addAll(index,Collection):
- remove(index)://删除指定位置的元素。
- set(index,element)://修改指定位置的元素。
- get(index)://通过索引获取元素。
- subList(from,to)://获取from到to之间的元素,包含头不包含尾。
- ListIterator():重点,List特有迭代器。参看DemoList.java。
- int indexOf(Object o):返回列表中元素第一次出现的索引,不存在则返回-1。
- int lastIndexOf(Object o):返回列表中元素最后一次出现的索引,不存在返回-1。(索引还是从前到后。)
(1)ArrayList
在迭代List集合的过程中,是不能调用集合的方法来增删改查,否则会并发异常。
但是,List集合有专门的迭代器:ListIterator是Iterator的子接口,它可以在遍历过程中增删改查(Iterator只能删)。
正向遍历:
List<String> arrayList = new ArrayList<String>(); arrayList.add("周杰伦"); arrayList.add("蔡依林"); arrayList.add("刘德华"); arrayList.add("张学友"); Iterator<String> iterator = arrayList.iterator(); while (iterator.hasNext()) { String name = iterator.next(); System.out.println("名字:" + name); }
当然还可以使用ListIterator来进行遍历,不但可以增删改,还可以反向遍历。
反向遍历:
List<String> arrayList = new ArrayList<String>(); arrayList.add("周杰伦"); arrayList.add("蔡依林"); arrayList.add("刘德华"); arrayList.add("张学友"); ListIterator<String> listIterator = arrayList.listIterator(arrayList.size()); while (listIterator.hasPrevious()) { System.out.println("名字:" + listIterator.previous()); }
(2)Vector
- 和ArrayList一样是数组数据结构。
- jdk1.0之前用的,在jdk1.2之后,被ArrayList替代。
迭代方式:
Vector<String> vector = new Vector<String>(); vector.add("周杰伦"); vector.add("蔡依林"); vector.add("刘德华"); vector.add("张学友"); Enumeration<String> elements = vector.elements(); while (elements.hasMoreElements()) { String name = elements.nextElement(); System.out.println("name:" + name); }
(3)LinkedList
- addFirst()://将指定元素插入此列表的开头。
- addLast()://将指定元素添加到此列表的结尾。
- getFirst()://获取此列表的第一个元素。(获取不删除)如果为空则报异常
- getLast()://获取此列表的最后一个元素。(获取不删除)如果为空则报异常。
- removeFirst()://获取并移除此列表第一个元素(获取并删除)如果为空则报异常。
- removeLast()://获取并移除此列表最后一个元素。(获取并删除)如果为空则报异常。
注意:当LinkedList列表为空的时候,进行移除操作会抛出异常:NoSuchElementException :没有这个元素,所以以后用替代的方法。
JDK1.6之后新的替代方法:
- (1)offerFirst()://将指定元素插入此列表的开头。
- (2)offerLast()://将指定元素添加到此列表的结尾。
- (3)peekFirst()://获取此列表的第一个元素。(获取不删除)如果为空不会报异常,返回null。
- (4)peekLast()://获取此列表的最后一个元素。(获取不删除)如果为空不会报异常,返回null。
- (5)pollFirst()://获取并移除次列表第一个元素。(获取并删除)如果为空不会报异常,返回null。
- (6)pollLast()://获取并移除次列表最后一个元素。(获取并删除)如果为空不会报异常,返回null
LinkedList<String> linkedList = new LinkedList<String>(); linkedList.add("周杰伦"); linkedList.add("蔡依林"); linkedList.add("刘德华"); linkedList.add("张学友"); Iterator<String> iterator = linkedList.iterator(); while (iterator.hasNext()) { String name = iterator.next(); System.out.println("name:" + name); }
LinkedList有特殊的迭代器,可以在迭代过程中进行增删改查操作。
2、 Set
(1)HashSet
底层数据结构是哈希表。"线程是非同步的"。(元素是无序的)保证元素唯一性的原理:判断hashCode值是否相同,如果相同继续判断元素的equals方法是否为真。
// 重写equals方法演示 public boolean equals(Object obj) { if (!(obj instanceof Person)) return false;// 或者抛出ClassCastException:类型转换异常。 Person p = (Person) obj;// 当加入泛型后不用转型。 return this.name.equals(p.name) && this.age == p.age; } // 重写hashCode方法演示 public int hashCode() { return name.hashCode() + age * 37; }
迭代方式:
Set<String> hashSet = new HashSet<String>(); hashSet.add("周杰伦"); hashSet.add("蔡依林"); hashSet.add("刘德华"); hashSet.add("张学友"); Iterator<String> iterator = hashSet.iterator(); while (iterator.hasNext()) { String name = iterator.next(); System.out.println("name:" + name); }
(2)TreeSet
- 可以对Set集合中的元素进行排序。(自然排序)
- 底层数据结构是二叉树。
- 保证元素的唯一性的依据:compareTo方法return 0。为0时表示主要条件相同,我们应该判断次要条件。
用法:对要排序的类实现 Comparable 接口,重写compareTo()方法。(和hashCode没关系)
(1)第一种排序方式:
让元素自身具备比较性。元素需要实现 Comparable 接口,覆盖compareTo方法。这种方式称为元素的自然排序(默认排序)。
class Student implements Comparable<Student> { private String name; private int age; public boolean equals(Object obj) { if (!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); Student s = (Student) obj; return this.name.equals(s.name) && this.age == s.age; } public String toString() { return "[" + name + age + "]"; } // 如果不确实是否存入hashSet中的话需要重写hashCode方法。 public int hashCode() { return age * 38; } // 重写compareTo方法 public int compareTo(Student s) { int num = new Integer(this.age).compareTo(new Integer(s.age)); // 主要条件满足,判断次要条件。 if (num == 0) return this.name.compareTo(s.name); return num; } }
(2)第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的。
- 这时就需要让集合自身具备比较性。在集合初始化时就有了比较方式。
- 当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。
- 定义比较器:定义一个类,实现 Comparator 接口,覆盖compare方法。
- 定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
public class Demo<T> { private static Student s1; private static Student s2; public static void main(String[] args) { s1 = new Student(); s2 = new Student(); TreeSet ts = new TreeSet(new myCompare()); } //自定义比较器 class MyCompare implements Comparator<Student>{ public int compare(Student s1,Student s2){ int num = s1.getName().compareTo(s2.getName()); //判断次要条件 if(num == 0) return Math.abs(s1.getAge() - s2.getAge()); return num; } } }
########################