------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
集合类概述
Java中的集合对象就类似于一个容器,用来存放Java类的对象。并且在Java的众多集合类中,由于数据在内存中存储方式的不同,有些类方便存放和取出,有些类就方便查找。在java.util包中就提供了一些集合类,这些类也被称为容器。在这里我们容易想到数组,因为数组也是容器。在这里说明集合类与数组的不同之处:数组的长度是固定的,集合长度可变;数组用来存放基本类型的数据,集合用来存放对象的引用。我们常用的集合有List集合、Set集合、Map集合,而List和Set实现了Collection接口。以下是常用的集合类之间的继承关系图。
集合类接口的常用方法
Collection接口是层次结构中的根接口,通常不能直接使用,但是提供了添加、删除、管理数据的方法。因为List接口和Set接口都实现了Collection接口,所以List和Set也能使用它们父类的方法。
List接口的常用方法
void add(int index,Object obj):把obj添加到角标为index的位置处,index之后的数据后移。
boolean addAll(int index,Collection coll):向集合的指定索引位置添加指定的集合对象,成功返回true。
Object remove(int index):移除集合中指定索引位置的对象。
Object get(int index):或者指定索引位置的对象。
int indexOf(Object obj):返回列表中对象第一次出现的索引位置。
Object set(int index,E element):用指定元素替换列表中指定位置的元素,并返回被替换的元素。
ListIterator listIterator():获得一个包含所有对象的ListIterator列表迭代器。
Set接的口常用方法
boolean add(Object obj):如果set集合中还没有存在指定的元素,则添加此元素。
boolean addAll(Collection coll):将参数集合中的所有元素添加到此set集合的尾部。
boolean remove(Object obj):删除指定的参数。
boolean retainAll(Collection c):只保留set集合中的包含在指定的Collection集合中的内容。
int size(): 返回set集合中的元素个数。
Iterator iterator():返回set中元素上进行迭代的迭代器。
boolean isEmpty():判断set是否包含元素。
Map接口的常用方法
/**
* 1.添加
* put(K key,V value) 添加一个键值对
* putAll(Map<? extends K,? extends V> m) 添加一个map对象
* 2.删除
* clear() 删除map对象中的所有键值对
* remove(Object key) 删除指定key对应的键值对并返回value,如果键不存在,则返回null
* 3.判断
* containsKey(Object key)
* containsValue(Object value)
* isEmpty()
* 4.获取
* get(Object key)可以通过get的返回值来判断一个键是否存在
* size()
* values()
*
* entrySet()
* keySet()
* */
List接口的实现类
/**
* ArrayList类是基于数组实现的类,不多介绍;LinkedList类即实现了List接口,也实现了Deque接口
* 所以可以看成一个队列来使用,以下是LinkedList特有的方法:
* addFirst();
* addList();
*
* 获取元素,但不删除元素
* getFirst();
* getLast();
*
* 获取元素,但是删除元素。如果集合中没有元素,会出现NoSuchElemntExcepiton异常。
* removeFirst();
* removeLast();
*
* 在jdk1.6中出现了替代方法。
* 添加元素
* offerFirst();
* offerLast();
*
* peekFirst();
* peekLast();
* 获取元素,但不删除元素。如果集合中没有元素,会返回null。
*
* pollFirst();
* pollLast();
* 获取元素,但是元素被删除。如果集合中没有元素,会返回null。
* */
Set接口的实现类
/**
* Set:无序,不可以重复元素。
* |--HashSet:数据结构是哈希表。线程是非同步的。
* 保证元素唯一性的原理:判断元素的hashCode值是否相同。
* 如果相同,还会判断元素的equals方法,是否为true。
*
* |--TreeSet:可以对set集合中的元素进行排序。
* 底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0.
*
* TreeSet排序的第一种方式:让元素自身具有比较性。元素需实现Compareable接口,覆盖
* compareTo方法,这种方式也称为元素的自然顺序,也叫默认顺序。
*
* TreeSet的第二种排序方式
* 当元素自身不具备比较性时,或者具备的比较性不是所需要的。
* 这时就需要让集合自身具备比较性。
* 方法:在集合初始化时,就有了比较方式。
*
* 记住:排序时,当主要条件相同时,一定判断一下次要条件。
*/
Map接口的实现类
/**
* Hashtable:底层是哈希表数据结构,不可存入null键null值。该集合是线程同步的。jdk1.0效率低
* HashMap:底层是哈希表数据结构,允许使用null值和null键。该集合是不同步的。jdk1.2效率高
* TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
* */
以下是部分实现类的实例代码:
//LinkedList模拟队列的类:先进先出
class DuiLie{
private LinkedList link;
DuiLie(){
link = new LinkedList();
}
public void myAdd(Object obj){
link.addFirst(obj);
}
public Object myGet(){
//return link.removeLast();
return link.removeFirst();
}
public boolean isNull(){
return link.isEmpty();
}
}
以下是用TreeSet类和HashMap实现的关于Student对象的实例:
//TreeSet实现学生按照年龄优先排序
TreeSet<Student> ts = new TreeSet<Student>();//<>表示泛型
ts.add(new Student("lisa02",22));
.
.
.
Iterator<Student> it = ts.iterator();//迭代器
while(it.hasNext()){ //获得对象的详细信息
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
class Student implements Comparable //该接口强制让学生具备比较性。需要实现Comparable接口
{
private String name;
private int age;
//省略部分方法
public int compareTo(Object o) {
//return -1; //简易方法。
//第一步,先判断传入的对象是否为Student对象
if(!(o instanceof Student))
throw new RuntimeException("不是学生对象");
//再把object对象强制转换为Student类型的对象
Student s = (Student)o;
//System.out.println(this.name+"...compareto..."+s.name);
//安装年龄进行比较
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
}
}
//HashMap实现学生排序
HashMap<Student,String> hm = new HashMap<Student, String>();
hm.put(new Student("lisi",21), "beijing");//添加n个学生信息
//Map映射中两种获得key和value值的方法
//第一种取出的方式,效率较低
Set<Student> keyset = hm.keySet();
Iterator<Student> it = keyset.iterator();
while(it.hasNext()){
Student student = it.next();
String addr = hm.get(student);
System.out.println(student+".."+addr);
}
//第二种取出方式entrySet,效率较高
Set<Map.Entry<Student, String>> entrySet = hm.entrySet();
Iterator<Map.Entry<Student, String>> itr = entrySet.iterator();
while(itr.hasNext()){
Map.Entry<Student, String> entry = itr.next();
Student stu = entry.getKey();
String addr = entry.getValue();
System.out.println(stu+"---"+addr);
}
}
}
//某个类可能创建多个种类的对象的时候,需要完成实现comparable和覆盖HasHCode和equals方法。
class Student implements Comparable<Student>
{
private String name;
private int age;
//省略部分方法
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;
}
public int hashCode(){
return name.hashCode()+age*34;
}
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;
}
}
总结
在使用集合的时候,在创建集合对象时,通常会使用泛型来帮助编译时检查错误,比如new一个ArrayList<String>()类型的list集合,这样我们在add的时候只能添加String类型的数据,添加其他的数据则会提示错误。还有实现Comparator接口或Comparable来对数据进行比较等等。这些都需要我们花很多的时间来研究。