java集合1
作者:互联网
目录
数组的缺点
1、长度开始时必须指定,一旦指定,不能更改
2、保存的必须是同一数据类型的元素
3、对数组元素的增删改查(crud)操作比较麻烦
集合
1、可以动态保存任意多个对象(类型可以不同) ,如果是基本数据类型会自动装包
2、集合含有许多方法,方便进行crud操作
集合的框架
图一:
图二:
分析:
1、集合主要主要是两组(单列集合[图一] 、双列集合[图二])
2、Collection 接口有两个重要的子接口 List Set , 他们的实现子类都是单列集合
3、Map 接口的实现子类 是双列集合,存放的K-V
(单列集合) Collection接口和它的实现类
Collection接口下又有两个接口继承了它,分别是List接口 和 Set接口
分析:
1、Collection接口的所有实现子类可以存放多个元素,每个元素都可以是Object
2、对于List接口的实现子类,可以存放重复的元素,而对于Set接口的实现子类,不允许存放重复元素
3、List接口的实现子类中的元素是有序的,而Set接口中的实现子类是无序的
对Collection集合作进一步说明
Collection接口形式:public interface Collection<E> extends Iterable<E>
说明:
1、 <E>是泛型,集合可以使用泛型向集合中传入一个参数(引用类型),来指定元素存储的类型,如果不传默认是Object
2、在创建对象时 可以使用泛型来限定元素的存储类型
3、集合存储的元素是引用类型(对象),如果存储基本数据类型,系统自动会包装成引用类型对象
具体实现:Collection是一个接口,所以只能通过实现子类来创建对象,这里以ArrayList来创建对象
public class Test {
public static void main(String[] args) {
/*
Collection<E> c = new ArrayList<T>();
在多态实现时,编译看左边,左边的泛型就会控制集合中元素的类型必须是 E 或者是E的子类
右边的泛型,是运行时类型其中的T必须和E一致 或者 是E的子类
一般形式:左边的泛型存在右边没有,或者右边的泛型存在左边没有
例如:Collection<String> c = new ArrayList<T>();
要求 c这个集合中 只能添加String 类型的元素 通过add方法 添加元素
Collection<String> c = new ArrayList<>();
c.add("hello world");
c.add("!");
System.out.println(c);
结果是:[hello world, !]
如果添加的元素不是String类型,则会直接编译不通过
*/
Collection<String> c = new ArrayList<>();
c.add("hello world");
c.add("!");
System.out.println(c);
}
}
ArrayList类的介绍:
ArrayList是一个集合类,可以存储多个重复的元素,且底层是一个数组
ArrayList类的构造方法:
1、无参构造器
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是一个空数组
在使用无参构造器创建对象时,在底层的数组会是一个空数组
当添加第一个元素时,它会自动扩容成含有10个容量的数组
可以发现,数组的容量发生了变化
查阅源码得到
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
//DEFAULT_CAPACITY数值为10 无参构造器minCapacity=0
会得到一个容量为10的数组
2、有参构造器
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
会得到一个给定容量大小的数组
ArrayList集合类的扩容
实质:对底层数组的更新,通过Arrays.copyOf返回一个新的长度的数组
扩容的细节:1、使用无参构造器构造对象,初始化容量为0,第一次添加元素,则扩容为10,如果还需要再次扩容,则扩大为1.5倍
2、使用有参构造器构造对象,初始化容量为指定的大小,如果需要扩容,则直接扩大1.5倍
Collection中定义的一些抽象方法,在这里具体通过ArrayList创建的对象,所以这里的方法我们认为是ArrayList重写Collection的方法
ArrayList类中的add 方法
源码:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
对源码的解释说明:
1、ArrayList集合类的底层是一个数组:transient Object[] elementData;
elementData数组存储着元素,ArrayList类对它进行维护
2、在进行添加元素之前需要先进行一个判断,判断这个底层数组是否已经被装满,如果被装满就需要对数组进行扩容,如果没有就直接在末尾添加元素即可
判断是否需要扩容的源码
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
3、因为集合可以动态扩容,所以需要有个变量来记录存储了多少元素,size来记录已经存储的元素的个数
ArrayList类中的size 方法
作用:得到ArrayList对象中的元素个数
格式:对象名.size();
实例演示:
public class Test {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("中");
list.add("国");
System.out.println(list.size());
/*
结果:2
*/
}
}
ArrayList类中的get 方法
作用:通过索引取得索引位置上的元素
格式:对象名.get(int index);
实例演示:
public class Test {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("中");
list.add("国");
System.out.println(list.get(0));
/*
结果:中
*/
}
}
ArrayList类中的indexOf方法
作用:返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
格式:对象名.indexOf(Object o);
实例演示:
public class Test {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("中");
list.add("国");
System.out.println(list.indexOf("中"));
}
}
类似的方法还有:
对象名.remove(int index); 删除并返回指定索引的元素
对象名.remove(Object o); 删除指定的对象并返回布尔值,如果删除成功则返回true,否则返回false
对象名.set(int index,Object o); 用指定的对象替换指定索引位置的元素
ArrayList类中的sort 方法
作用:对数组元素按照比较器排序
格式:对象名.sort(Comparator<? super E> c)
sort括号中接口的定义
方法一:匿名内部类
public class Test {
public static void main(String[] args) {
ArrayList<Integer> alist = new ArrayList<>();
alist.add(1);
alist.add(0);
alist.add(-3);
alist.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(alist);
}
}
方法二:创建类来实现
public class Test {
public static void main(String[] args) {
ArrayList<Integer> alist = new ArrayList<>();
alist.add(1);
alist.add(0);
alist.add(-3);
ComparatorDemo c = new ComparatorDemo();
alist.sort(c);
System.out.println(alist);
}
}
class ComparatorDemo implements Comparator<Integer>{
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
}
方法三:直接将方法作为参数
public class Test {
public static void main(String[] args) {
ArrayList<Integer> alist = new ArrayList<>();
alist.add(1);
alist.add(0);
alist.add(-3);
alist.sort((Integer o1,Integer o2)->{ return o1-o2; });
System.out.println(alist);
}
}
未完待续......
标签:java,ArrayList,元素,alist,Collection,add,集合,public 来源: https://blog.csdn.net/HuierHUI/article/details/121733381