java集合框架list和set
为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一中方式
数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的.
数组中可以存储基本数据类型,集合只能存储对象.
集合只用于存储对象,集合程度是可变的.集合可以存储不同类型的对象.
Collection
|--List:,元素是有序的元素可以重复.因为该集合体系有索引.
|--ArrayList: 底层的数据结构使用的是数组结构.
特点:查询速度很快,但是增删稍慢.线程不同步所以速度快.
|--LinkedList: 底层使用链表数据结构. 特点:增删速度很快,查询稍慢.
|--Vector: 底层是数组数据结构.线程同步,所以速度超慢,被ArrayList替代了.
|--Set:元素是无序,元素不可以重复.
List集合特有的迭代器.ListIterator是Iterator的子接口.
package pack; import java.util.ArrayList; import java.util.ListIterator; public class Demo { public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("litiepeng"); al.add("chenhaigeng"); al.add("pengjie"); ListIterator<String> listIterator = al.listIterator(); while (listIterator.hasNext()) { String next = listIterator.next(); System.out.println(next); } } }
ArrayList可以通过iterator()迭代元素
在迭代时,不可以通过集合对象的方法操作集合中的元素.
因为会发生ConcurrentModificationException异常
所以,在迭代器,只能用迭代器的操作元素,
方法是有限的.只能对元素进行判断,取出删除操作.
如果想要其他的操作,如添加,修改,就需要使用其的子接口,ListIterator.
List集合特有的迭代器.ListIterator是Iterator的子接口.
package pack; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class Demo { public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("litiepeng"); al.add("chenhaigeng"); al.add("pengjie"); Iterator<String> iterator = al.iterator(); while(iterator.hasNext()){ String str = iterator.next(); System.out.println(str); } //ListIterator 是iterator的 子类, 他比父接口多了add set 方法 ListIterator<String> listIterator = al.listIterator(); while (listIterator.hasNext()) { // String next = listIterator.next(); listIterator.add("yanxiong"); System.out.println(next); } } }
public ArrayList()
构造一个初始容量为 10 的空列表。 如果超过了就在创建一个新的数组,延长50%,把前面的复制在这后面,然后把新的添加再后面.
Vector:向量的大小大于其容量时,容量自动增加的量。
elements
枚举就是Vector特有的取出方式
发现枚举和迭代器很像
其实枚举和迭代是一样的
因为枚举的名称以及方法的名称过长
所以迭代器取代了.
枚举消失了.
LinkedList.pollFirst();和LinkedList.removeFirst();这两个的功能一样,移除后返回移除的元素,不过对于空链表,removeFirst()会返回异NoSuchElementException,pollFirst()直接返回null.一个报异常,一个返回0
当list集合是对象的话,要重写equals,因为底层比较元素是否相同用的是equals,
如果是基本数据元素就不用重写equals了
List集合判断元素是否相同,依据是元素的equals方法.
contains() remove()底层是调用 equals比较的.
Set:
Set集合的功能和Collection是一致的.
Set:无序,不可以重复元素.
|--HashSet: 数据结构是哈希表,线程是非同步.
HashSet是如何保证元素唯一性的呢?
通过元素的两个方法,hashCode和equals来完成.
如果元素的HashCode值相同,才会判断equals是否为true.
如果元素的hashcode值不同,不会调用equals.
注意,对于判断元素是否存在,以及删除remove()和是否包含contains()等操作,依赖的方法是元素的hashCode和equalse方法.
package pack; import java.util.ArrayList; import java.util.HashSet; import java.util.concurrent.ArrayBlockingQueue; public class Demo{ public static void main(String[] args) { ArrayList<Student> al = new ArrayList<Student>(); System.out.println(al instanceof ArrayList); al.add(new Student("张三", 21)); al.add(new Student("赵六", 22)); al.add(new Student("王武", 23)); al.add(new Student("王武", 23)); for (Student student : al) { System.out.println(student.toString()); } HashSet<Student> hs = new HashSet<Student>(); hs.add(new Student("张三", 21)); hs.add(new Student("赵六", 22)); hs.add(new Student("王武", 23)); hs.add(new Student("王武", 23)); for (Student student : hs) { System.out.println(student.toString()); } } } class Student{ String name; int age; Student(String name,int age){ this.name = name; this.age = age; }
//重写equals @Override public boolean equals(Object obj) { // TODO Auto-generated method stub if(this == obj) return true; if(obj == null) return false; if(!(obj instanceof Student)) return false; Student s2 = (Student) obj; return new Integer(this.age).equals(new Integer(s2.age)); } @Override public String toString() { // TODO Auto-generated method stub return "name:"+name+"age:"+age; } }
|--TreeSet :可以对Set集合中的元素进行排序.
底层数据结构是二叉树.
保证元素唯一性的依据.
compareTo方法ret urn0;
TreeSet排序的第一种方式:让元素自身具备比较性,元素需要实现Comparable接口,覆盖compareTo方法.这种方式也成为元素的自然顺序,也叫叫做默认顺序.
TreeSet的第二种排序方式
把比较对象作为构造函数的参数传递进去. 让那个参数实现Comparator 接口覆盖compareto方法
当元素自身不具备比较性时,或者具备的比较性不是所需要的.
这是就需要让集合自身具备比较性.
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数
里面增加的自定义值必须能自动排序,如果不能自动排序,就会报错误,Comparable
当两种排序都存在时,以比较器为主
//创建构造器
package pack; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; public class TreeSetDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TreeSet<Computer> ts = new TreeSet<Computer>(new myComparator()); ts.add(new Computer("zhangsan", 10)); ts.add(new Computer("zhaosi", 15)); ts.add(new Computer("xiaosi", 20)); Iterator<Computer> iterator = ts.iterator(); while (iterator.hasNext()) { Computer computer = iterator.next(); System.out.println(computer.toString()); } } } //简单构造器,比较字符串大小 class myComparator implements Comparator { public int compare(Object o1, Object o2) { // TODO Auto-generated method stub Computer s1 = (Computer) o1; Computer s2 = (Computer) o2; int num = new Integer(s1.age).compareTo(new Integer(s2.age)); if (num == 0) { return s1.name.compareTo(s2.name); } return num; } } // 有泛型 class myComparator2 implements Comparator<String> { public int compare(String o1, String o2) { // TODO Auto-generated method stub int num = new Integer(o1.length()).compareTo(new Integer(o2.length())); if (num == 0) { return o1.compareTo(o2); } return num; } } class Computer { Computer(String name, int age) { this.name = name; this.age = age; } String name; int age; @Override public String toString() { // TODO Auto-generated method stub return "name:" + name + " age" + age; } }
//实现comparable接口
//实现comparable接口 使用在set里面 class Student implements Comparable{ String name; int age; Student(String name,int age){ this.name = name; this.age = age; } public int compareTo(Object obj) { // TODO Auto-generated method stub if(!(obj instanceof Student)) throw new RuntimeException("不是学生对象"); Student s = (Student)obj; if(this.age>s.age){ return 1; } if(this.age == s.age){ return this.name.compareTo(s.name); } return -1; } }