- JDK中的对象集合,依据其实现的接口,大致上可分为四类:
- Set:无序,不可重复
- List:有序,可重复
- Map:具有映射关系的集合
- Queue:具有队列特性的集合
JDK中集合相关的接口和类
Collection是JDK中集合类型的上层接口,很多相关接口和集合类都派生自(或实现)它
- 实际上是“对象组合”的编程方式,以基础集合类型为底层,向其中增加某些函数,构造出功能更加强大的新集合类型。
- 基础集合类型
Array Linklist Hashtable Tree
集合分类
名称 | 特点 |
---|---|
Set | 无序、不可重复 |
List | 有序、不可重复 |
Queue | 队列 |
Map | 具有映射关系的集合 |
集合中的常见操作
JDK中相应的集合类型提供了相应的方法,实现响应的操作(因为所有的集合都应该具有这些功能,不是属于集合的个性,而是集合的共性,是按方法重写的)
如果一个集合直接用println进行打印,是这种形式[xxx,xxx,xxx]
- 遍历
- 按内容进行查找
- 向集合中插入元素或删除元素
int size();//返回当前集合的大小
boolean isempty();//返回当前集合是否为空
boolean contains(Object);//判断集合中是否含有Object这个对象
boolean containsAll(Collection<?>);
Iterator<E> interator();//生成迭代器
Object[] toArray();
<T> T[] toArray(T[]);
boolean add(E);//向集合中添加元素
boolean addAll(Collection<?>);//判断Collection<?>中的元素是不是全部属于当前调用这个函数的集合
boolean remove(Object);//从集合中移除元素
void clear();//清空集合
boolean retainAll(Collection<?>);//移除不属于集合Collection<?>中的元素,如果发生移除,返回true
boolean equals(Object);//判断两个集合是否相等
int hashcode();//返回对应的hash值
⚠️在向集合中添加元素的时候,加入的都是对象, JDK的集合中不能保存基本数据类型的数据
Collection c = new Array();
c.add(2);
上面的添加的2会进行自动装箱,调用Integer.valueOf()函数返回一个Integer类型的对象
遍历操作
一般有两种遍历操作:for循环;foreach循环
在介绍两种循环的时候首先介绍一下Iterator类,即迭代器类。所有Collection类都实现了Iterator()方法,派生自Iterable接口。Iterator定义了三种方法如下:
boolean hasNext();//判断当前的集合是否已经遍历结束,或者为空
E next();//返回当前集合的下一个元素,要根据具体元素进行转换
void remove();//remove the last element returned by the iterator
迭代器的简单使用:
Collection c = new Array();
Iterator i = c.iterator();
while(i.hasnext()){
System.out.println(i.next());
}
//先创建一个集合类然后通过集合的内置函数iterator返回一个Iterator对象i,再通过i对集合进行一些遍历操作
Iterator遍历:
while(i.hasnext())
{
System.out.println(i.next());
}
foreach遍历
for(Object obj:c)
{
E x = (E)obj;
System.out.println(x);
}
foreach实际上是基于Iterator实现的,是对Iterator遍历实现的一种封装。
- 关于Iterator()的实现原理:
实际上是在每个实现Iterator()方法的集合中,都定义了一个私有内部类,这个内部类中是对hasnext() next() remove()
等方法的实现,然后返回一个Itr类型的对象
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;//标识当前对象修改次数(包括remove和add方法)
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
⚠️不能使用集合本身的元素进行添加元素和删除元素,否则会出现concurrentModificationException的异常(如果要删除元素,只能用迭代器自带的remove()方法
)但是注意这实际上不是绝对的
public static void main(String[] args)
{
Collection<String> books = new HashSet<>();
books.add("One book");
books.add("Two book");
books.add("Three book");
System.out.println("‘≠ º‘™Àÿ÷Æ∫Û£∫"+books);
Iterator<String> it = books.iterator();
/*while(it.hasNext())
{
String book = (String)it.next();
System.out.println(book);
//note: »Áπ˚…æ≥˝"Two book",±æ æ¿˝≤ªª·“˝∑¢“Ï≥££¨«ÎÕ®π˝≤È—Ø‘¥¬ÎΩ‚ Õ’‚“ªœ÷œÛ
if (book.equals("One book"))
{
// π”√Iteratorµ¸¥˙π˝≥Ã÷–£¨≤ªø…–fi∏ƒºØ∫œ‘™Àÿ£°
books.remove(book);
}
}*/
//这里会报错
for (String book : books) {
if (book.equals("Two book"))
{
books.remove(book);
}
}//这样并不会报错
System.out.println("“∆≥˝‘™Àÿ÷Æ∫Û£∫"+books);
}
详细分析,见链接:https://blog.csdn.net/red_sheeps/article/details/79952794
这个作者的分析思路特别好,也同时告诉我平时应该怎么逐步去定位、去分析问题和解决问题