1.ArryList 类中有add()、get(int i)、size()方法,当直接打印ArrayList对象时会调用对象的toString()方法打印集合里面的元素进而调用元素的toString方法打印每个元素的内容。
2.ArrayList类中有方法toArray()会返回一个装有集合对象里面所有元素的对象数组,Arrays类有一个静态方法asList(Object[] objs)返回一个含有所有数组元素的list集合对象,这个集合对象的长度是固定的。所以若想把一个List集合对象中的元素放到数组中用toArray方法,若想把数组里面的元素放到一个list集合对象中用Arrays类的asList方法。
3.List里面有一个方法set(int index,E element)用一个元素替换指定位置上的元素并返回原来的元素。
4.Collection接口里面有一个iterator()方法返回一个Iterator迭代器,由于ArrayList实现了Collection接口所以也实现了iterator方法返回一个迭代器实现ArrayList的遍历。
Iterator接口里面有hasNext()、next()、remove()等方法,其中hasNext()判断下一个是否还有元素若有返回true,next()方法返回下一个元素,remove()方法是一个选择实现方法即有的类实现了这个方法有的类没有实现这个方法(如Arrays类的asList(Object[ ] obj)方法返回的List对象不能改变长度),remove方法必须在next方法之后调用可以返回next方法返回的那个元素。
只要是实现了Collection接口的集合类都可以使用iterator迭代器遍历集合中元素。
public static void printElements(Collection<?> c)
{
Iterator<?> it = c.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
5.LinkedList是采用双向循环链表实现的,LinkedList类有addFirst(E e)、addLast(E e)、getFirst()、getLast()、removeFirst()、removeLast()等方法所以可以使用LinkedList实现栈(stack)、队列(queue)、双向队列(double end queue)。
下面使用LinkedList类实现一个栈:
class MyStack
{
private LinkedList ll = new LinkedList();
public void push(Object obj)
{
ll.addFirst(obj);
}
public Object pop()
{
return ll.removeFirst();
}
public Object peek()
{
return ll.getFirst();
}
public boolean isEmpty()
{
return ll.isEmpty();
}
}
队列是一种只能从一端加入(队尾),只能从另一端取出(队头)属于先进先出的链式结构,用LinkedList实现队列:
class MyQueue
{
private LinkedList ll = new LinkedList();
public void put(Object obj)
{
ll.addLast(obj);
}
public Object get()
{
return ll.getFirst();
}
public boolean isEmpty()
{
return ll.isEmpty();
}
}
6.ArrayList底层采用的是数组实现,而linkedList则是用一般的双向链表实现,其内每个对象除了数据本身之外,还有两个引用分别指向前一个和后一个元素。如果我们经常对List对象中的元素进行添加和删除操作选用LinkedList完成效率比较高,如果只是经常对List集合中的元素读取可以使用ArrayList完成,因为ArrayList中添加一个元素时会导致其余全部元素的移动。
7.HashSet类有add方法可以添加元素没有get方法要获得HashSet里面的元素只有通过遍历获得。HashSet实现了Set接口所以不能有重复元素。List是有序可以重复的,Set是无序不可重复的。
8.当用HashSet存放对象时,为了避免存放相同的对象我们要给要存放的对象实现两个函数hashCode()、equals()。hashCode()方法返回用于计算对象在集合中存放位置的数据。equals()方法用于判断是否为相同的元素。如下:
class Student
{
int num;
String name;
public Student(int num,String name)
{
this.num = num;
this.name = name;
}
public int hashCode()
{
return num*name.hashCode();
}
public boolean equals(Object o)
{
Student s = (Student)o;
return num == s.num & s.name.equals(s.name);
}
public String toString()
{
return num+":"+name;
}
}
9.TreeSet存放的字符串元素时都会按照自然排序,由于HashSet是基于Hash算法实现的其性能一般都优于TreeSet,所以一般我们都使用HashSet只有需要我们对元素排序时才会使用TreeSet。
TreeSet存放元素时会对元素进行排序,所以我们创建元素的类时该元素的类就要实现Comparable接口,也就是实现了接口里面的comparaTo(Object obj)方法。当然我们也可以在创建TreeSet集合时为其指定一个所存放元素的比较器TreeSet(Comparator comparator)。由于Comparator比较器是一个接口所以可以用匿名类为其传递参数(接口名加上实现接口的类实体)。
下面是在对象元素中实现比较方法的例子:
class Student implements Comparable
{
int age;
String name;
public Student(int age,String name)
{
this.age = age;
this.name = name;
}
@Override
public int compareTo(Object o)
{
if(!(o instanceof Student))
throw new RuntimeException("对象类型不对!");
Student st = (Student)o;
if(this.age>st.age)
return 1;
if(this.age == st.age)
return 0;
return -1;
}
}
public static void main(String[] args)
{
Student st0 = new Student(1,"a");
Student st1 = new Student(2,"b");
Student st2 = new Student(3,"c");
Set<Student> set = new TreeSet<Student>();
set.add(st0);
set.add(st2);
set.add(st1);
Iterator<Student> it = set.iterator();
while(it.hasNext())
{
System.out.println(it.next().name);
}
}
还有一种就是在TreeSet中加入一个比较器的例子:
Set set = new TreeSet<Student>(new Comparator(){
@Override
public int compare(Object obj1, Object obj2)
{
Student st1 = (Student)obj1;
Student st2 = (Student)obj2;
return st1.age-st2.age;
}
});
10.HashMap里面存放的是键值对,我们可以使用put(key,value)向集合中添加数据,也可以使用方法get(key)从集合中获取数据。我们也可以使用方法public Set keySet()方法返回一个存有HashMap中所有key的set集合,也可以使用public Collection values()方法返回一个存有HashMap中所有值的Collection类型的集合。TreeMap里面存放的也是键值对,只是它里面的元素按照key进行排序。
11.在非同步的的情况下我们用ArrayList代替Vector,用HashMap代替HashTable。在同步的情况下也可以通过Collections类的Map<key,value> synchronizedMap(Map<key,value> m)和List<T> synchronizedList(List<T> list)方法获得相应的线程安全的集合,但是其效率要比Vector和HashTable慢。Collections类可以看成是实现了Collection接口集合的工具类,它提供了一系列的对集合操作的静态类。
12.只有对象存放在Hash集合中时,元素的hashCode方法才会对该元素在集合中的存放位置有影响。当元素对象实现了hashCode()方法,并存放在Hash集合中,改变对象中hashCode()方法运算的变量则对象在集合中存放的位置也将会发生改变,这时使用集合的remove()方法移除对象时其实并没有将对象真的移除,因为对象在集合中存放的位置已经方法变化发生了内存泄漏。
13.Properties类表示一个持久的属性集,由于该类是HashTable的子类所以该类中存储的键值对且键值都是String类型的。Properties可以保存在流中或从流中加载。可以同过getProperties(String key)方法从集合中获取数据,通过setProperties(String key,String value)方法向集合中添加数据。public Enumeration propertyNames()方法可以得到一个包含属性集中所有键的枚举。枚举可以通过boolean hasMoreElements()方法判断是否还有值,E nextElement()方法取出值,也就是遍历集合。
14.集合类和接口的实现关系如下:
从上可以看出:ArrayLsit和LinkedList存放数据时ArrayLsit访问速度快,LinkedList方便对里面数据的增删查找等操作。
HashSet和TreeSet存放数据都是不可重复的,而不同之处是TreeSet是有排序的。
HashMap和TreeMap存放的都是键值对,只是TreeMap进行了排序。
ArrayList和Vector都存放的是链表,前者访问速度快,后者线程安全。
HashMap和HashTable都存放的是键值对,前者访问速度快,后者线程安全。