java 集合类

java集合类


1、java类库中的集合接口和迭代器接口
java类库中用于集合类的基本接口是Collection接口,该接口有如下两个基本方法:
public interface Collection<E>
{
    public boolean add(E element);
    Iterator<E> iterator();
}
迭代器接口 Iterator<E>有如下方法:
public interface Iterator<E>
{
    E next();
    boolean hasNext();
    void remove();
}
遍历集合: 
Collection<String> c = ....;
Iterator<String>iter = c.iterator();
while(iter.hasNext())
{
    String element = iter.next();
    do something;
}
对于实现了Iterator接口的类,可以使用 for each循环,即
Collection<String> c = ...;
for(String s : c)
   do something;


    java 集合类库中的迭代器与其他类库中的迭代器在概念上有一个很重要的区别。在传统的集合类库中,比如c++的stl中,迭代器是根据数组索引来
建模的。如果给出这样的一个迭代器,可以查找存放在某个位置上的元素,如果使用数组索引i来查找 数组元素 a[i], 不需要元素的查找操作就
可以将迭代器向前移动到下一个位置。即可以在不执行查找的情况下,用i++操作来向前移动数组索引;
    而java迭代器的查找操作和位置的变更是紧密相连的,查找一个元素的唯一方法是调用next,而执行该查找操作的同时会使迭代器的位置向前移动。
即,java迭代器是位于各个元素之间的,当调用next方法时,迭代器便越过下一个元素,并且返回它刚刚越过的那个元素的引用。


Iterator接口的remove方法将会移除上次调用next方法时返回的元素。大多数情况下,在确定应该移除某元素之前,先看看该元素是否很有实际意义。
但是,如果想移除特定位置上的元素,仍然需要跳过该元素。例如,删除某个字符串集合中的第一个元素:
Iterator <String> it = c.itarator();
it.next(); //跳过第一个元素
it.remove(); //移除第一个元素
next方法和remove方法的调用是相互依赖的,如果调用remove之前,没有先调用next方法,则是不合法的。如果尝试这样使用,则抛出一个IllegalStateException异常。


List列表有两种实现方法:1、ArrayList<T> 数组列表,便于随机访问、修改; 2、LinkedList<T> 链表列表,便于随机插入、修改


LinkedList<T> 链表列表:
java集合类库提供了LinkedList,作为链表使用。链表在随机的插入删除方面由于数组。
List<String> staff = new LinkedList<String>();
staff.add("Amy");
staff.add("Bob");
staff.add("Carl");
Iterator iter = staff.iterator();
String first = iter.next();
String second = iter.next();
iter.remove(); //删除上一个访问的元素,即second
  LinkedList<T>集合类还含有一个包含add方法的子接口ListIterator.
public interface ListIterator<E> extends Iterator<E>
{
    void add(E element);
    ...
    bolean hasNext();
    E next();
    boolean hasPrevious(); //是否含有前一个元素
    E previous(); //返回前一个元素
    void set(); //修改值
}
previous()返回它跳过的对象(和next相同)。
   ListIterator的remove方法移除迭代器刚跳过的对象;add方法,始终在iterator之前添加元素。


List<String> staff = new LinkedList<String>();
staff.add("Amy");
staff.add("Bob");
staff.add("Carl");
ListIterator<String> iter = staff.ListIterator(); //返回头迭代器
iter.next();
iter.add("test"); //该元素被添加到第二个位置,同时迭代器指在第二个元素后。(add方法将新元素添加到迭代器位置的前面)
iter.previous();  //迭代器指到第一个元素后
iter.add("test2"); //该元素被添加到


ListIterator ::set方法,能够用一个新元素取代通过调用next或者previous方法返回的上一个元素。
ListIterator<String> iter = list.listIterator();
String oldValue = it.next();
iter.set(newValue);


如果某个迭代器在另一个迭代器修改某个集合之前遍历该集合,那么就可能出现混乱。例如,假设一个迭代器指向另一个迭代器刚刚移除掉的
元素的前面,那么这个迭代器现在就是无效的,而且不应该在使用。链表迭代器的设计使得他能够检测到这种修改,如果一个迭代器发现他的集合
已经被另一个迭代器修改了,或者别该集合自身的方法修改了,那么就会抛出一个 ConcurrentModifucationException异常。
    为了避免冰法修改列表的异常发生,可以根据你的需要给容器附加许多的只读迭代器,另外再附加一个读写迭代器。使用一种简单的方法可以探测到
冰法修改列表的问题,集合可以跟踪改写操作(比如添加和移除元素)的数量,每一个迭代器都维护一个独立的计数值,记录着该迭代器负责的改写
操作的数量,在每个迭代器方法开始处,迭代器都要检查自己的改写操作计数值和集合的改写操作计数值是否一致。如果不一致,则抛出
ConcurrentModifiicationException异常。

   数组列表 ArrayList<T> 速记读取十分方便。 通过set(), get(),可以随机读取、复制。


   链表和数组能够确定用什么样的顺序来安排元素,但是如果要查找的某个特定的元素,并且不知道该元素的位置,那么就必须访问所有的元素,直到
找到匹配的元素为止。使用散列表可以在不知道元素位置的情况下,通过元素本身快速查找所需要的元素。 散列表为每个对象计算出一个整数,为散列码。
散列码通过 hashCode()方法产生。
   自定义类需要重写hashCode方法(如果需要用到散列表存储),hashCode方法必须和equals方法兼容: 如果 a.equals(b) 为true,则a和b的散列码相同。


    散列表是个链表的数组,每个列表成为一个散列表元。若要查找表中某个对象的位置,只要计算出它的散列码,再将它对散列元的总数取余数,得到的数
即为该对象所在的散列表元号,然后进入该散列表元(即一个链表)中进行顺序查找或插入。
    java集合类库提供了HashSet列,实现了基于散列表的散列集。(散列集就是不存在重复元素的集合,散列集的add方法受喜爱你尝试查找要添加的对象,
并且只有在该对象不存在的情况下才添加该对象。) HashSet可以使用 add方法来添加元素,contains方法被重新定义用来快速查找散列集中是否存在某个元素,
它只检查某个表元中的各个元素,而不检查集合中的所有元素。
Set<String> words = new HashSet<String>(); //HashSet实现了Set接口
words.add("test");
words.add("xxx");
Iterator<String> iter = words.iterator();
for(int i = 0; i < 2; i ++)
    System.out.println(iter.next());
   TreeSet 树集类和散列表相类似,只不过它是一个有序集合,可以按照任何顺序将元素插入该集合。当对该集合进行迭代时,各个值将自动以排序后的顺序出现。
TreeSet使用红黑树数据结构,每当把一个元素添加到树集合中时,该元素会被放置到恰当的排序位置。因此,迭代器总是按照排序后的顺序来访问各个元素。
   在默认条件下,树集假设你插入的元素实现了Comparable接口,该接口定义了方法 。
public interface Comparable<T>
{
    int compareTo(T other);
}
如果a,b相等,则返回0,若a<b,返回负整数,否则返回正整数。
如果需要插入自己定义的对象,则必须通过实现Comparable接口来自定义一个排列的顺序,Object类中的compareTo方法没有提供默认的实现。
如果一种对象需要在不同的TreeSet中采用不同的排序方式,但是只能实现同样的compareTo方法。这种情况下,可以让树集使用不同的比较方法,将一个Comparator对象
传递给TreeSet类的构造器。Comparator接口声明一个compare方法,它带有两个显式参数:
public interface Comparator<T>
{
    int compare(T a, T b);
}
例如:
class ItemComparator implements Comparator<Item>
{
    public int compare(Item a, Item b)
    {
String descrA = a.getDescription();
String descrB = b.getDescription();
return descrA.compareTo(descrB);
    }
}
ItemComparator comp = new ItemComparator();
SortedSet<Item> sortBySescription = new TreeSet<Item>(comp);


    PriorityQueue 优先级队列是一种能够在以任意顺序插入元素后,再按排序顺序读取这些元素的数据结构,即当你调用remove方法时,返回当前优先级队列中的最值。
和TreeSet一样,优先级队列所持有的元素可以是实现了Comparable接口的类的对象,也可以是在构造器中提供的Comparator对象。




映射表
  键值对map。分为 散列映射表(*HashMap)和树状映射表(TreeMap).两者都实现了Map接口。
散列映射表只对键进行散列,而树状映射表则利用键的全局顺序进行排序。散列函数或比较函数只能作用于键。 和散列集一样,散列映射表的运行速度比较快,如果
不需要按照排列顺序来访问键的话,最好选择散列映射表。
Map<String, Employee> staff = new HashMap<String, Employee>();




   集合框架并不将映射表本身视为一个集合(其他的数据结构框架则将映射表视为对的集合,或者视为由键索引的值的集合)。但是,可以得到映射表的视图,一组实现了
Collection接口的对象,或者他的子接口的一个视图。可以得到三个视图,即键集(Set<K> keySet()得到)、值集合(值本身不是集, Collection<K> values()得到)、
以及键值对的集(Set<Map.Entry<K, V>> entrySet()得到)。键和建制度构成一个集,应为映射表中只有一个键的副本。如果对keySet/entrySet/values集合中的元素进行
操作(如删除),则原来的映射表map中相应的也会改变。


  keySet 不是HashSet和TreeSet,它是实现了Set接口的某个其他类的对象,Set接口拓展了Collection接口,因此,可以像使用任何集合一样使用keySet。
Set<String> keys = map.keySet();
for(String key: keys)
{
  do something with key;
}


   栈  Stack
java.util.Stack<E> java标准库中有一个栈类,其主要方法:
E push(E item)  //将item压入栈中,然后返回item
E pop() //弹出和返回栈顶项,如果栈是空的,不能使用该方法
E peek() //返回栈顶项而不将它弹出。如果栈是空的,不能使用该方法。


   位集 BitSet
   java平台的位集类用于存放一个位序列。由于位集将各个位包含在字节中,因此使用位集比使用 Boolean对象的ArrayList更为高效。BitSet类提供了
一个使用起来非常方便的接口,可以对各个位进行读取、设置或者清除等操作。使用该接口后,就可以避免屏蔽以及其他麻烦的位操作,如果将位存放在int
或 long 变量中,就必须进行繁琐的操作。
位集的主要方法有:
BitSet(int capacity);//构建一个位集
int length(); //返回位集的逻辑长度(即1加上位集的最高位的索引)
boolean get(int bit); //获取一个位
void set(int bit);//置位一个位
void clear(itn bit);// 清除一个位
void and(BitSet set);//将该位集和另一个位集进行逻辑与
xor 异或
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值