变量—容器:存储一个元素
数组—容器:一组具有某种特性的数据存放在一起;存储一组元素(数据类型一致)
长度固定自己定义了Box(ArrayBox LinkedBox)----容器:用来存储一组元素,长度可变
集合—容器:与数组类似,集合的长度存储之后还能改变集合是用来存储一组元素可以理解为集合是我们封装的Box ,只不过比我们写的更加的优秀 ,更多的方法
集合
1.集合需要导包:java.util
2.分类:Collection和Map
Collection Map
存储的都是value 存储的是以key-value形式存在
List Set
有序可重复 无序无重复 key无需无重复 value无需可重复
序 : 顺序,添加进去的元素与取得元素的顺序一致,注意指的不是集合自己的顺序
重复:两个对象元素一致
迭代器
对 Collection 进行迭代的类,称其为迭代器。还是面向对象的思想,专业对象做专业的事情,迭代器就是专门取出集合元素的对象。但是该对象比较特殊,不能直接创建对象(通过new),该对象是以内部类的形式存在于每个集合类的内部。
Iterator it = list.iterator(); //定义一个迭代器
while (it.hasNext()) {
String str=it.next();//取走迭代器中的元素,至于取走的元素是什么类型的根据迭代器迭代的集合决定
}
泛型
关于泛型的问题:由于arrayList底层是一个Object[] ,什么类型都可以存进去 ,取出来的时候多态的效果,需要自己造型, 显得用起来非常的麻烦。
JDK1.5之后—>泛型 :用来规定数据类型的,定义的时候用一个符号代替某种类型。
在使用的时候用具体的数据类型 ,将定义的那个符号替换掉
泛型可以用在哪里?
- 泛型类 :类定义的时候描述某种数据类型 集合的使用就是这样
- 泛型接口:与泛型类的使用基本一致 子类实现接口时必须添加泛型
- 泛型方法:方法调用时传参数 方法的泛型与类无关 带有泛型的方法可以不放在带有泛型的类中
- 高级泛型 规范边界 extends super
List集合
List集合:1.ArrayList 3.Vector 2.LinkedList
ArrayList适合遍历循环,Vector是ArrayList的早期版本,现在不是很需要。LinkedList是链表格式,适合插入和删除,但是不适合遍历。
一. ArrayList
ArrayList----->底层就是一个数组
- 所属的包 java.util
- 如何创建对象?
- 无参数构造方法
- 带默认空间的构造方法
- 带collection参数的构造方法
ArrayList list = new ArrayList();
表示list容器中可以存放各种类型的数据
list.add(“abc”)
List.add(2)
但是我们定义的容器往往只需要存储一组相同的数据类型,所以可以应用泛型,表示这个容器只能存储这一种类型的数据,其他类型的数据不允许存储,会报错。
ArrayList<String> list = new ArrayList<String>();
<String>
表示泛型,只能存储String类型的数据。
list.add(“abc”)
没任何问题
List.add(2)
会报错,因为你存储的是int类型的数
- 常用的方法—小容器:
常用的方法:
存 addlist.add("a");
取 getlist.get(0);
-------a
删 remove
改 set
个数 size:有效元素的个数
//输出list中的所有元素
ArrayList<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
for(int i=0;i<list.size();i++){
String value = list.get(i);
System.out.println(value);
}
//输出结果:
//a
//b
//c
//也可以直接打印list
System.out.pritln(list);//list底层重写了toString方法
//结果[a,b,c]
//通过遍历的方法删除集合中的全部元素的方法:
//集合的元素全部删掉
int size = list.size();//5
for(int i=0;i<size;i++){
list.remove(0);
}
其他方法:
add(E e)
add( index,E e)
addAll(Collection c);
add(int index,Collection c)
clear();
将集合内的全部元素清除
boolean = contains(Object);
找寻某一个给定的元素是否在集合中拥有 ensureCapacity(int minCapacity);
E = get(int index);
int = indexOf(Object obj);
lastIndexOf();
boolean = isEmpty();
Iterator = list.iterator();
//迭代器
remove(int index)
remove(Object obj)
removeAll()
差集
retainAll();
交集
E = set(int index,E value)
int size();
List = subList(int begin,int end);
toArray();
集合变成数组
toArray(T[] );
trimToSize();
// 变成有效元素个数那么长
总结:
增删改查:add(E e); remove(index) ; set(index value) ; get(index) size();
类中其他常用的方法:addAll并集;removeAll差集;ratainAll交集; indexOf() ; lastIndexOf() ; contains() ;List=subList(); isEmpty() ; clear() ; ensureCapacity() ; iterator();迭代器 ; toArray(T[] x); trimToSize();
toArray方法的使用:
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
// 转为 Object[] 再做类型转换
Object[] objectArray = list.toArray();
for (Object o : objectArray) {
Integer number = (Integer) o;
System.out.println(number);
}
// 直接一步到位
Integer[] actualArray = list.toArray(new Integer[0]);
for (int i : actualArray) {
System.out.println(i);
}
//另一种一步到位
Integer[] array2 = list.toArray(new Integer[list.size()]);
二. Vector
ArrayList Vector区别—>StringBuilder StringBuffer
- java.util包
- 是ArrayList集合的早期版本 (StringBuffer早期,StringBuilder后来) Vector底层也是利用(动态)数组的形式存储
Vector是线程同步的(synchronized) , 安全性高, 效率低 - 扩容方式与ArrayList不同
默认是扩容2倍,可以通过构造方法创建对象时修改这一机制Vector<String> vector = new Vector<String>();
默认容量是10,扩容是2倍
Vector<String> vector = new Vector<String>(4);
给定一个初始容量4,扩容仍然是2倍
Vector<String> vector = new Vector<String>(4,5);
给定初始容量是4,扩容是每次扩容5个可以通过以下代码进行验证:
Vector<String> vector = new Vector<String>(4,4);
for(int i=1;i<=22;i++){
vector.add("a");
System.out.println(vector.size()+"--"+vector.capacity());
//有效元素个数 底层真实数组的容量
}
- 构造方法
- 常用方法
三. Stack类 栈
继承了Vector,只不过多了一些方法,特点是先进后出。
- java.util包
- 构造方法只有一个无参数
- 除了继承自Vector类的方法外还有特殊的方法
push(E e)
将某一个元素压入栈顶(add())
E = pop()
将某一个元素从栈顶取出并删掉(E = remove())
E = peek()
查看栈顶的一个元素 不删除(get())
boolean = empty()
判断栈内元素是否为空(isEmpty())
int = search()
查找给定的元素在占中的位置(indexOf()) - 什么时候用?
中国象棋 悔棋
栈中存储每一次操作的步骤 撤销功能
Stack<String> stack = new Stack<String>();
stack.push("a");
stack.push("b");
stack.push("c");
System.out.println(stack);//[a,b,c]
System.out.println(stack.peek());//c
System.out.println(stack);// [a,b,c]
System.out.println(stack.search("b"));//2 不是索引 是第几个
四. Queue接口(不常用)
- java.util
通常子类LinkedList ArrayDeque - 通常无参数构造方法创建
LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。
eg:Queue<String> queue = new LinkedList<String>();
- 一般方法
boolean = offer(E e);//相当于add 不会抛出异常
E = peek();//相当于 element方法
E = poll();剪短// 相当于remove()
add()
element()---->get()
remove() - 应用:
双十一零点秒杀 所有进入秒杀系统的人存入队列
五. LinkedList类
- java.util包
自己封装过LinkedBox,内部类Node对象(节点 prev item next) - 底层使用双向链表的数据结构形式来存储
适合于插入或删除 ,不适合遍历轮询 - 构建对象
无参数构造方法
带参数的构造方法(collection) - 常用的方法
常用方法实例参考博客
增删改查 : add() ; remove() ; set() ;get() ; size() ;offer; poll ; peek ;
手册中提供的其他常用方法:addAll; addFist ; addLast() ; clear() ; contains();element() ; getFirst() ; getLast() ;indexOf() ;lastIndex();…
//LinkedList 200000次为例
//向后追加元素 4
//向前插入元素 4
//遍历轮询元素 4 元素太少,和ArrayList相比较变化不大,实际上LinkedList的轮训遍历时间应该慢一些
//ArrayList 200000次为例
//向后追加元素5
//向前插入元素4005
//遍历轮询元素3