------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Java 的集合框架为我们提供一些存储数据的容器对象,这些容器对象各自有不同的底层数据结构。
相比数组存储数据而言,这些容器具有长度可变,可存储多种数据类型数据的特点。Java根据各个类型容器底层数据结构的不同,对容器进行了封装。并提供一些常见的数据操作方法。方便开发人员的调用。
1 java中的集合框架如下图所示:
Iterator :迭代器
迭代器的产生: Java为每个集合容器(不包括map)定义 定义了一个内部类对象用于获取集合中的元素对象。但因为每个集合容器的底层数据结构不同,所以取出元素的具体操作细节也不同。但这些操作都存在一些共性:1 判断是否存在;2 取出 。于是Java就对这些操作进行了提取并定义为了Iterator接口;并让各个集合容器的内部类去实现这个接口。并提供iterator()方法返回此内部类对象。给调用者,以便获取集合中的元素。
Iterator 中的主要方法:
boolean hasNext() :判断
E next(): 获取
void remove()
collection:集合:单列元素容器,一次只能存入一个对象。
|-----List::可存储重复元素,有序(存入顺序和取出顺序相同)。具有索引
|-----Set::不能存储重复元素,无序。没有索引
collection 中的常见操作
1 添加元素
void add(E )
void addAll(Collection <? Exrends E>c)
2 删除
void clear():
boolean remove(Object o):当删除对象
3 判断
boolean contains(Objet o)
boolean isEmpty();
4 获取:
int size():获取集合中元素的个数
Iterator<E> iterator():获取操作集合类元素对象的内部类对象
获取集合中的所有元素的方法:
Iterator <E> it = 集合容器对象.iterator();
while(it.hasNext)
{
E itme = it.next();
}
5 注意:Collection中并未有修改操作
-----------------------------------------------
List:体系
|-----ArrayList: 底层数据结构数组,默认长度10,当长度不够时会创建一个长度为原长度1.5倍长的新数组将原数组中的元素拷贝。线程不同步的
常用方法:
1 增加
void add(E):
void add(index ,E):指定位置添加
2 删除
void clear(): 清空
E remove(index):删除指定位置元素, 返回被移除元素
boolean remove(Object 0):
3修改:
E set(index ,newE):替换指定位置的元素,返回被替换的元素
4 获取
int size():
E get(index):获取指定位置的元素
获取集合中的所有元素的方法:
Iterator <E> it = 集合容器对象.iterator();
while(it.hasNext)
{
E itme = it.next();
}
5判断
boolean isEmpty();
boolena contains(Object):判断元素是否存在
注意:contains(Object)底层依赖的是存入元素的equals()方法,当在ArrayList()中存入自定义对象时,需要复写equals()方法,在该方法中定义自己判断该类对象相同的规则。如果不进行复写,进行Contains()判断时调用的是Object类的equlas()方法,默认比较的是内存地址值。
|-----LinkedList:底层数据结构是:链表。增加,删除的效率高。查询效率慢
当需要对存入元素进行频繁char删除操作时选择LinkedList
常见使用方法:
除拥有ArrayList的全部方法外:自己特有的方法
1 添加
void addFirst(E e);
void addLast(E e);
2 获取:获取元素但不删除元素
如果集合中没有元素会出现NosuchElementException;
E getFirst();
E getLast();
3 删除元素: 获取元素但删除元素
如果集合中没有元素会出现NosuchElementException;
E removeFirst();
E removeLast();
JDK1.6替代方法
offerFirst();
offerLast();
pickFirst();
pickLast();
获取元素,但元素不被删除,如果集合中没有元素,会返回NULL;
pollFirst();
pollLast();
获取元素,但元素被删除,如果集合中没有元素,会返回NULL;
|-----Vector: 底层数据结构为数组,线程同步的。现已经被ArrayList取代。(java1.0出来的)长度不够时每次增加100%的长度
-----------------------------------------------------------------
Set :存储元素不重复,无序。无索引:Set中的方法与Colletion中的完全一致
|---HashSet: 底层数据结构为哈希表。
存入对象时会:调用存入元素的hascode()方法,与容器中对象的hashcode()值进行比较
如果相同:则会调用存入元素的equlas()方法来判断是否存在相同元素
如果不同:则直接存入。
由上述机制,往HashSet容器中存入自定义对象时,需要复写自定义对象的hashCode()方法,和equlas()方法。否则存入的数据可能出现重复的问题.
Object默认的hashCode()实现为地址值得16进行表述
实例:
class Person1
{
private String name;
private int age;
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;
}
public Person1(String name,int age)
{
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
System.out.println("-----hashCode--");
return this.name.hashCode()+age*37;//通常不返回固定的hash值,通常定义一个获取hash值的方法
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person1))
return false;
System.out.println(this.name+"--equals--"+((Person1)obj).getName());
return this.name.equals(((Person1)obj).getName())&&
this.age == ((Person1)obj).getAge();
}
}
|---TreeSet:底层数据结构为二叉树,会对存入元素进行排序操作(默认为自然排序)
存入元素时会对元素进行排序,因此存入元素必须具备可比性,或者在创建容器时为TreeSet容器指明该容器中元素的比较规则。
在TreeSet中是如何保证元素的唯一性的?
当存入元素是 会调用元素的compareTo() 方法,如果该方法返回值为0值判定存在重复元素。
当往TreeSet中存入基本数据类型数据时存在一个自动装箱动作是的存入元素具备可比性,所以能存入。
当往TreeSet集合中存入自定义对象时有2种处理方式
1 让元素具备可比性:实现comparable接口复写compareTo() 方法。 在该方法中指明该类对象的比较规则
实例:
class Student implements Comparable//必须是可比的方式一:让元素自身具备可比性
{
private String name;
private int age;
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;
}
public Student (String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)//复写comparable接口的方法定义自己的比较规则
{
if(!(obj instanceof Student))
throw new RuntimeException("元素类型不同不能进行比较");
// 定义自己的比较规则
Student s2 = (Student)obj;
if(this.age >s2.getAge())
return 1;
if(this.age == s2.getAge())//当主要条件相同时,比较次要条件
{
return this.name.compareTo(s2.getName());
}
return -1;
}
}
2 定义比较器在创建容器时通过构造参数传入给TreeSet容器,为容器指明比较规则
步奏:1 定义一个类实现comparator接口
2 复写compare()方法;在方法中指明比较规则
实例
class mycomapareRul implements Comparator
{
@Override
public int compare(Object arg0, Object arg1) {
// TODO Auto-generated method stub
System.out.println("--compare--");
if(!(arg0 instanceof Student)&&(arg1 instanceof Student) )
throw new RuntimeException("不同类型元素不能进行比较");
//指定规则为按姓名比较进行排序
Student s1 = (Student)arg0;
Student s2 = (Student)arg1;
if(s1.getName().compareTo(s2.getName()) == 0)// 姓名相同比较年龄
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return s1.getName().compareTo(s2.getName());
}
}
-------------------------------------------------------------------------------
Map:映射关系存储容器:存入的是键值对.map中必须保证键的唯一性.
|----hashMap:底层数据结构是哈希表,不同步,键和值运行为NULL;
|---TreeMap:底层数据结构是二叉树,不同步
|--Hashtable:内部结构是哈希表,时同步的。不允许空作为键,值(和vector一个时期出现的早于map)
|--Properties:用来存在键值对型的配置文件的信息。可以和IO技术相结合。
Map常见方法:
1 添加
void put(key, value);
2 删除
void clear();:清空
Value remove(key);
3 判断
boolean isEmpty();
boolean containsKey(key);
boolean containsValue(Value);
4 获取
Value get(key);
int size();
Set<Key> keySet():返回键集合//用于取出map中的所有对象
Set<Map.Entry<Key ,Value>> entrySet();//返回Map中的关系映射集合// 用于取出map中的所有元素
5 修改操作
Value repalce(Key, newValue);:修该指定键的值并返回之前的值
------------------------
HashMap:
注意事项:因为Map中必须保证键的唯一性,所以当键为自定义对象时需要复写自定义对象的hashcode()方法和equlas()方法。具体实现参见上述HashSet的实现。
如果不进行复写会造成键的不唯一性。
TreeMap
注意事项:treemap会对键进行排序操作,所以必须保证键具备可比较性(实现comparable接口,复写compareTo()方法),或者在创建TreeMap对象时为其指定比较器对象(实现comparator接口复写compare(Object obj1,Object obj2)类对象)
----------------
Map 容器中取出所有元素的方式
1
</pre><pre name="code" class="java">{
Set<Key> keyset = map.keySet();//获取map中的键集
Iterator<Key> it = keyset.iterator();//
while(it.hasNext())//取出所有的键值
{
Key key = it.next();
Value v = map.get(key);// 通过键值取得value值
}
}
// 方式2
{
Set<Map.Entry<Key, Value>> entryset = map.entrySet();//获取map类的键值映射关键集合
Iterator<Map.Entry<Key, Value>> it = entryset.iterator();
while(it.hasNext())//取出所有键值映射关系
{
<pre name="code" class="java"> Map.Entry<Key, Value> me = it.next();
Key key = me.getKey();//通过映射关系对象获取键
Value v = me.getValue();//通过映射关系对象获取值
}
}
//说明:Entry为Map的内部接口且是静态的