集合:就是一个存储数据的容器。
集合与数组一样,也是一个容器,与数组的区别:
1 数组长度固定,集合的长度不固定。
2 数组可以存储基本类型和引用类型,集合中存储的元素类型只能是引用类型。
ArrayList类是List接口的大小可变数组的实现。
实现了所有可选列表操作,并允许包括null在内的所有元素。
存储特点:
相对有序存储,可以存储相同元素(不排重),
可以通过下标访问集合元素,通过数组实现的集合
存储结构:数组
底层是数组:所以下标是自带属性,长度固定
但是我们集合是长度不固定
构造方法
初始化数组,这个数组的容量为0
注意:很多面试宝典中说ArrayList的数组初始化容量为10,这是错的
当第一次调用add这个方法,此时会对数组进行扩容,并且将容量赋值为10,
并且将第0个下标赋值为你add的值,扩容代码如下:
//数组扩容的代码
private void grow(int minCapacity) {//10
// overflow-conscious code
int oldCapacity = elementData.length;//0
int newCapacity = oldCapacity + (oldCapacity >> 1);//0
if (newCapacity - minCapacity < 0)
//吧最小的容量10赋值新容量
newCapacity = minCapacity;
//数组的容量绝对不能超过2的31次方-1
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);
}
第二次赋值,会将原数组进行copy,然后复制到新的数组,
该新的数组容量为15[原长度+原长度的一半](),以此类推。
//数组第n次扩容的代码(n>1)
private void grow(int minCapacity) {//11
// overflow-conscious code
int oldCapacity = elementData.length;//10
int newCapacity = oldCapacity + (oldCapacity >> 1);//15(原length+length的一半)
if (newCapacity - minCapacity < 0)
//吧最小的容量10赋值新容量
newCapacity = minCapacity;
//数组的容量绝对不能超过2的31次方-1
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他的底层就是数组,下标是自带属性,所以在做查找和修改的速度会比较快
但是由于数组的增加会牵扯到扩容,删除的时候会对元素进行覆盖,
所以ArrayList在做数据的增删时,效率比较低
package net.csdn.blog.wdd9527.week04.day02.Test02;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class Test3 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("张三1",22 , '男', 80));
list.add(new Student("张三2",22 , '女', 89));
list.add(new Student("张三3",22 , '女', 81));
list.add(new Student("张三4",22 , '女', 88));
list.add(new Student("张三5",22 , '女', 82));
list.add(new Student("张三6",22 , '男', 87));
list.add(new Student("张三7",22 , '男', 83));
list.add(new Student("张三8",22 , '女', 86));
list.add(new Student("张三9",22 , '女', 84));
list.add(new Student("张三0",22 , '男', 85));
//求男女人数
System.out.println("男生女生数:");
int count = 0;
for (int i = 0; i < list.size(); i++) {
if ('男' == list.get(i).getSex()) {
count++;
}
}
System.out.println("男生人数为:" + count);
System.out.println("女生人数为:" + (list.size() - count));
//成绩
System.out.println("成绩:");
double sum = 0;
for (int i = 0; i < list.size(); i++) {
sum += list.get(i).getGrade();
}
System.out.println("总成绩为:" + sum);
System.out.println("平均成绩为:" + sum/list.size());
//张三0改为李四5,张三5的年龄改为18
System.out.println("张三0改为李四5,张三5的年龄改为18");
for (int i = 0; i < list.size(); i++) {
if ("张三0".equals(list.get(i).getName())) {
list.get(i).setName("李四5");
}
}
for (int i = 0; i < list.size(); i++) {
if ("张三5".equals(list.get(i).getName())) {
list.get(i).setAge(18);
}
}
//打印
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i).toString());
}
//删除张三5 (删除不要用for-each)
/*for (Student student : list) {
if ("张三5".equals(student.getName())) {
//ConcurrentModificationException异常
list.remove(student);
}
}*/
System.out.println("删除张三5");
for (int i = 0; i < list.size(); i++) {
if ("张三5".equals(list.get(i).getName())) {
list.remove(i);
}
}
//for-each打印
for (Student s:list) {
System.out.println(s.toString());
}
//排序
System.out.println("按成绩排序后:");
/*//冒泡排序
for (int i = 0; i < list.size() - 1; i++) {
for (int j = 0; j < list.size() - 1 - i; j++) {
if (list.get(j).getGrade() < list.get(j + 1).getGrade()) {
Student temp = list.get(j);
list.set(j, list.get(j + 1));
list.set(j + 1 , temp);
}
}
}*/
/*//选择排序
for (int i = 0; i < list.size()-1; i++) {
for (int j = i + 1; j < list.size(); j++) {
if (list.get(i).getGrade() < list.get(j).getGrade()) {
Student temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
}*/
//使用Collections工具类来进行排序
//你使用对象去进行排序,那么该对象知道你的排序规则吗?
//需要去告诉我们的对象,需要我们javaBean来实现Compareable接口,
//并且重写他的抽象方法compareTo
Collections.sort(list);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i).toString());
}
}
}
如果想使用Collections.sort()的方法对集合进行排序
1.首先泛型类型的javaBean必须实现Comparable接口,并且将T改成该Bean类型
2.重写compareTo方法,重设对象之间排序条件,此时用属性进行对比,
返回正数,0,负数即可(具体升序降序,看你返回的数)
3.如果对对象数组也想使用Arrays.sort(),同理
基本使用和ArrayList没有任何一点点区别
LinkedList类是List接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括null)。
存储特点:
相对有序存储,可以存储相同元素(不排重),可以通过下标访问集合元素,通过链表实现的集合
存储结构:双向链表
ArrayList存储结构是数组,LinkedLis存储结构是链表。
ArrayList集合适用在对元素查询、遍历操作,不适合插入和删除。
LinkedList集合适用在对元素插入和删除操作,不适合遍历和查找。
ArrayList与LinkedList,Vector三种实现类存储的比较?
a.功能基本相同
b.底层存储结构:ArrayList是数组,LinkedList是链表,Vector是数组
c.Vector是一个古老的集合,从JDK1.0开始就有了,Vector存在一些方法名比较长的方法,xxxElement
d.Vector是线程安全的,效率低,ArrayList是线程不安全的,效率高,
推荐使用ArrayList【Collections工具类中有相应的方法可以将ArrayList改为线程安全的】
e.ArrayList查找遍历比较快,LinkedList插入删除比较快