您的位置:首页 > 编程语言 > Java开发

Java核心技术卷一 第13章 集合

2015-08-20 22:06 417 查看
第13章 集合

13.1 集合接口

13.1.1 将集合的接口和实现相分离

13.1.2 Java类库中的集合接口和迭代器接口
在Java类库中,集合类的基本接口是Collection接口。这个接口有两个基本方法:
public interface Collection<E>
{
boolean add(E element);
Iterator<E> iterator(); //返回该对象的迭代器
. . .
}
add方法用于向集合中添加元素。如果添加元素确实改变了集合就返回true,如果集合没有发生变化就返回false。例如,如果试图向集合中添加一个对象,而这个对象在集合中已经存在,这个添加请求就没有失效,因为集合中不允许有重复的对象。
iterator方法用于返回一个实现了Iterator接口的对象。可以使用这个迭代期对象依次访问集合中的元素。
1.迭代器
Iterator接口包含3个方法:
public interface Iterator<E>
{
E next();
boolean hasNext();
void remove();
}
通过反复调用next方法,可以逐个访问集合中的每个元素。但是,如果到达了集合的末尾,next方法将抛出一个NoSuchElementException。因此,需要在调用next之前调用hasNext方法。如果迭代器对象还有多个供访问的元素,这个方法就返回true。如果想要查看集合中的所有元素,就请求一个迭代器,并在hasNext返回true时反复调用next方法。例如
Collection<String> c = ...;
Iterator<String> iter = c.iterator();
while(iter.hasNext())
{
String element = iter.next();

do something with element
}
从java SE5.0开始,这个循环可以采用一种更为优雅的缩写方式。用for each循环可以更加简练的表示同样的循环动作:
for(String element:c)
{
do something with element

}
编译器简单地将for each循环翻译为带有迭代器的循环。

for each循环可以与任何实现了Iterable接口的对象一起工作,这个接口只包含一个方法:
public interface Iterable<E>
{
Iterator<E> iterator();
}
Collection接口扩展了Iterable接口,因此,对于标准类库中的任何集合都可以使用"for each"循环。

元素被访问的顺序,取决于集合的类型。如果对ArrayList进行迭代,迭代器将从索引0开始,每迭代一次,索引值加1。
然而,如果访问HashSet中的元素,每个元素将会按照某种随机的次序出现。

应该将java迭代器认为是位于两个元素之间。当调用next时,迭代器就越过下一个元素,并返回刚刚越过的那个元素的引用。



2.删除元素
Iterator接口的remove方法将会删除上次调用next方法时返回的元素。在大多数情况下,在决定删除某个元素之前应该先看一下这个元素是很具有实际意义的。然而,如果想要删除指定位置上的元素,仍然需要越过这个元素。例如,下面是如何删除字符串集合中第一个元素的方法:
Iterator<String> it = c.iterator();
it.next();//skip over the first element
it.remove();//now remove it
如果想删除相邻的两个元素,不能直接地这样调用
it.remove();//now remove it

it.remove();//Error
相反地必须先调用next越过将要删除的元素
it.remove();

it.next();
it.remove();//OK

映射表
通常,我们知道某些键的信息,并想要查找与之对应的元素。映射表(map)数据结构就是为此设计的。映射表用来存放键/值对。如果提供了键,就能查找到值。
例如,有一张关于员工信息的记录表,键为员工ID,值为Employee对象。Java类库为映射表提供了两个通用的实现HashMap和TreeMap。这两个类实现了Map接口。
散列映射表对键进行散列,树映射表用键的整体顺序对元素进行排序,并将其组织成搜索树。散列或比较函数只能作用于键。
应该选择散列映射表还是树映射表呢?与集一样,散列稍微快一些,如果不需要按照排列顺序访问键,就最好选择散列。

下列代码将为存储的员工信息建立一个散列映射表:
Map<String,Employee> staff = new HashMap<>();
Employee harry = new Employee("Harry Hacker");
staff.put("987-98-9996",harry);

每当往映射表添加对象时,必须同时提供一个键。在这里,键是一个字符串。对应的值是Employee对象。
要想检索一个对象,必须提供(因而必须记住)一个键。
String s = "987-98-9996";
e=staff.get(s);//gets harry
如果在映射表中没有与给定键相对应的信息,get将返回null。

键必须是唯一的。不能对同一个键存放两个值。如果在同一个键上两次两用put方法,第二个值就会取代第一个值。
remove方法用于从映射表中删除给定键对应的元素,size方法用于返回映射表中的元素数。

有3个视图,它们分别是:键集、值集合、和键/值对集。键与键/值对形成了一个集,这是因为在映射表中一个键只能有一个副本。下列方法将返回这三个视图。

Set<K> keySet()
Collection<K> values()
Set<Map.Entry<K,V>> entrySet()
keySet既不是HashSet也不是TreeSet,而是实现了Set接口的某个其他类的对象。

可以枚举映射表中的所有键
Set<String> keys = map.keySet();
for(String key:keys)
{
do something with key
}

如果想要同时查看键与值,就可以通过枚举各个条目(entries)查看,以避免对值进行查找。
for(Map.Entry<String,Employee> entry:staff.entrySet())
{
String key = entry.getKey();
Employee value = entry.getValue();
do something with key,value
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: