集合(1)
概念当我们要保存一组一样的元素的时候,我们需要用一个容器来存储,数组就是这样的容器然而数组一旦被定义,那么他的长度将不会在变化然而在我们的生活以及开发实践中,很多东西并不是一直不变的,所以这个时候就需要可以根据我们所需要的容量的容器,也就是动态增长的容器,这个时候我们就需要集合集合APIjava的集合框架里有很多接口、抽象类、具体类,都位于java.util包中Collection接口Collec
概念
-
当我们要保存一组一样的元素的时候,我们需要用一个容器来存储,数组就是这样的容器
-
然而数组一旦被定义,那么他的长度将不会在变化
-
然而在我们的生活以及开发实践中,很多东西并不是一直不变的,所以这个时候就需要可以根据我们所需要的容量的容器,也就是动态增长的容器,这个时候我们就需要集合
集合API
java的集合框架里有很多接口、抽象类、具体类,都位于java.util包中
Collection接口
-
Collection接口中定义了存取一组对象的方法,子接口Set和List分别定义了不同的存储方式
-
List中的数据对象有顺序且可以重复
-
Set中的数据对象没有顺序且不可以重复
Collection
我们先来看一下Collection这个接口
-
Collection<E>集合可以使用泛型传入一个参数,如果不传入参数,那么默认是Object,都必须存储引用类型
Collection c = new ArrayList(); c.add("a"); c.add(1);//自动装箱为包装类型 c.add(true);
以上代码我们可以看出,如果不使用泛型传入一个参数的话,Collection就默认是Object,那么这个集合就不是那么精确了,这个集合我们就可以传入任何类型
Collection<String> c = new ArrayList<String>(); c.add("a");
c.add("b");
c.add("c");
c.add("d");
c.add("a");
//c.clear();//清空集合中的元素
//c.remove("a");//删除集合中的指定的第一次出现的元素 System.out.println(c.contains("a"));//是否包含指定元素 System.out.println(c.isEmpty());//集合是否为空 System.out.println(c.size());//集合的长度 System.out.println(c);
Object[] objs1 = c.toArray();//集合转数组 System.out.println(Arrays.toString(objs1));
String[] objs2 = c.toArray(new String[c.size()]);//集合转数组,指定集合类型
Collection<String> c1 = new ArrayList<String>();
c1.add("a");
c1.add("b");
c1.add("c");
c1.add("d");
//c.addAll(c1);//将c1中的全部元素加到c中
//c.removeAll(c1);//删除c1在c中的内容
//System.out.println(c.containsAll(c1));//c中包含了c1中的全部元素则返回true
System.out.println(c.retainAll(c1));//只保留c和c1中相交的部分,没有区别的情况下返回false
System.out.println(c);
System.out.println(c1);
-
当我们给Collection的泛型里传入一个参数的时候,这个集合就变得很精确了,比如Collection<String>那么这个集合表示的就是String类型,那么往里面添加元素也就只能传入String类型的值
-
同时我们可以用Collection里的方法,详情可以参照API里的各种方法
ArrayList类
-
ArrayList类是List接口中的类之一
-
该类实现了长度可变的数组,在内存中分配连续的存储空间
-
遍历元素比较快,也就是查询快,由于其底层实现是数组结构,所以增删慢
//ArrayList<>()创建一个长度为10的底层数组,第一次添加元素时,真正创建数组
//ArrayList<String> alist = new ArrayList<>();
ArrayList<String> alist = new ArrayList<>(20); alist.add("a");
alist.add("b");
alist.add("c");
//alist.add(0,"d");//向指定的位置插入数据
//System.out.println(alist.get(2));//return (E) elementData(index);
//System.out.println(alist.indexOf("b"));//找到该元素的位置
//System.out.println(alist.remove(1));//删除并返回该位置元素 alist.set(1, "B");//替换指定位置的元素 System.out.println(alist);
//ArrayList<>()创建一个长度为10的底层数组,第一次添加元素时,真正创建数组
//ArrayList<String> alist = new ArrayList<>(20);
/*
add()添加一个元素到集合中的一个过程
调用add()添加元素时,先检查底层数组是否还能放的下,如果可以,直接将元素添加到末尾,
如果不可以,会创建一个新的数组,将原来的数组内容复制过去
size --->记录实际装入数组的元素个数
public boolean add(E e) {
ensureCapacityInternal(size + 1); //检查元素能否放得进去
elementData[size++] = e;
return true;
}
放进去后容量大小 - 底层数组长度>0
if (minCapacity - elementData.length > 0)
grow(minCapacity);扩容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);新数组为原来的1.5倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);数组复制,创建一个新数组,将原来的数组内容复制到新数组中
}
*/
ArrayList<String> alist = new ArrayList<>();
alist.add("a");
alist.add("b");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
alist.add("c");
-
输出的顺序是按照添加的顺序排列
-
ArrayList默认创造一个底层为长度为10的数组,如果超过这个长度,会自动扩容,扩容的新数组为原来的1.5倍
-
长度不够的情况下,创建的新数组会将原来数组中的内容复制过去并加入新的元素
匿名内部类
ArrayList<String> alist = new ArrayList<>(); alist.add("c");
alist.add("b"); alist.add("a");
alist.add("d");
//new 接口(){方法重写} 创建了一个匿名内部类对象
/*alist.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});*/
//创建一个自定义String比较器类的对象
//alist.sort(new StringComparator());
alist.sort((String o1,String o2)->{return o1.compareTo(o2);}); System.out.println(alist);
//创建的自定义的String比较器类的对象
import java.util.Comparator;
public class StringComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}
-
匿名内部类这个概念我们只需知道有这么个东西,后面会加深理解
-
且匿名内部类写起来过去繁琐,后面学到的lambda表达式是对其的简洁表示
-
形如:alist.sort((String o1,String o2)->{return o1.compareTo(o2);});
LinkedList类
-
LinkedList是List接口中的一个实现类
-
该类采用链表存储方式。查询遍历较慢,插入、删除时效率较高
-
添加元素时,先判断Node结点是否为空,如果为空,就可以直接添加一个新元素,如果不为空,则会创建一个新的Node添加到下一位
/* 存储重复元素
add() 每添加一个元素创建一个Node对象
E item;
Node<E> next;
Node<E> prev; */
LinkedList<String> llist = new LinkedList(); llist.add("a");
llist.add("b");
llist.add("c");
llist.add("d");
llist.add("a");
//index<size/2从头结点开始向后找,否则从尾结点向前找 System.out.println(llist.get(3)); System.out.println(llist);}
-
输出的顺序是按照添加元素的顺序输出
-
因为LinkedList是双向链表,如果index<size/2就会从头找,反之,从尾结点开始找
-
所以LinkedList的增删效果块,查询效果慢
Vector类
/*Vector底层也是数组实现,但是是线程安全的
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e;
return true;} */
Vector<String> v = new Vector<>();
v.add("a");
v.add("a");
v.add("a");
v.add("c");
v.add("b");
v.add("d");
v.add("f");
v.add("a");
v.add("a");
System.out.println(v);
Vector底层也是数组实现,不过是线程安全的,不做强调
Iterator接口
-
是集合的迭代器,可用来遍历集合
-
迭代器允许调用者在迭代期间从底层集合中删除元素
ListIterator类
-
可接Iterator接口
ArrayList<String> alist = new ArrayList<>(); alist.add("a");
alist.add("b");
alist.add("c");
alist.add("d");
alist.add("a");
alist.add("a");
alist.add("a");
alist.add("b");
alist.add("c");
/*
for
*/
/*for (int i=0;i<alist.size();i++){ System.out.println(alist.get(i));
}*/
/* 增强for循环 */
/*for(String s:alist){
System.out.println(s);
}*/
/* 通过迭代器 */
/*Iterator<String> it = alist.iterator();//返回一个迭代器对象,控制元素的遍历 while (it.hasNext()){
String s =it.next(); System.out.println(s);
}*/
/*ListIterator<String> lit = alist.listIterator(); while (lit.hasNext()){ System.out.println(lit.next()); }*/
//listIterator() 只能对List接口下的实现类进行遍历 ListIterator<String> lit = alist.listIterator(alist.size()); while (lit.hasPrevious()){ System.out.println(lit.previous());
Iterator<String> it = alist.iterator();//返回一个迭代器对象,控制元素的遍历
while (it.hasNext()){
String s =it.next();
if (s.equals("a")){
it.remove();//使用迭代器中的方法进行遍历
}
}
System.out.println(alist);
-
通过迭代器我们可以删除多个相同的元素
-
也可以从后向前访问元素
更多推荐
所有评论(0)