1.Collection接口
集合: 存储数据的容器(数据结构)
Collection:是一个接口,定义了操作集合相关方法
Collection下有两个子接口
List
Set
(1)集合存储对象的引用
集合存储的是对象的引用地址值,而不是对象本身。存储原理参考对象数组。
(2)Collection常用方法
public static void main(String[] args) {
//测试Collection中常用方法
/*
<E>:泛型:
指定当前集合的存储元素
*/
//创建Collection对象//多态 向上造型
Collection<String> collection = new ArrayList<String>();//ArrayList继承了父类(Object类)中的toString()方法
//1.add 添加元素(可以是基本数据类型,可以是String类型,也可以是对象)
collection.add("java");
collection.add("c");
collection.add("c++");
collection.add("php");
System.out.println(collection);//[java, c, c++, php]
//2.contains(object o) 是否包含某个元素
System.out.println(collection.contains("java"));//true
//3.containsAll(Collection c)向一个集合中添加一个新的集合
Collection<String> collection_sub = new ArrayList<String>();//向上整型
//创建第二个集合,因为该方法参数为集合
collection_sub.add("java");//为第二个集合添加元素
collection_sub.add("c");
System.out.println(("当前集合为:"+collection_sub));
System.out.println(collection.containsAll(collection_sub));//true 判断是否包含整个集合
//4.size
System.out.println(collection.size());//4
//5.isEmpty():boolean
System.out.println(collection.isEmpty());//false
//6.remove(Object):boolean 删除某个元素
System.out.println(collection.remove("j"));//false
System.out.println(collection);//[java, c, c++, php]
//7.addAll(Collection<?>):boolean
System.out.println(collection.addAll(collection_sub));//true
System.out.println(collection);//[java, c, c++, php, java, c]
//8.removeAll(Collection<?>):boolean 删除上一个集合中下一个集合的元素
System.out.println(collection.removeAll(collection_sub));//true
System.out.println(collection);//[c++, php]
//9.retainAll(Collection<?>):boolean 保留当前集合元素,删除其他元素
System.out.println(collection.retainAll(collection_sub));//true
System.out.println(collection);//[]
//10.clear():void 全部清除
//11.toArray() toArray(T[] t) 集合只能存储对象 数组能储存
//常用 toArray(T[] t) :参数为转换后数组的指定类型
System.out.println(collection_sub);
String[] strings=collection_sub.toArray(new String[]{});
//String[] strings=collection_sub.toArray(new String[collection_sub.size()]);
System.out.println(Arrays.toString(strings));
//重点
Object[] objects =collection_sub.toArray();
//问题:
//怎么把Object类型数组转为String[]
//String[] Strings1=(String[])objects;//ClassCastException 向下造型
//System.out.println(String1);
//思路:先取出所有的Object对象,一一转为String类型再存储到String类型的数组中
String[] strings2=new String[objects.length];
for (int i = 0; i <objects.length ; i++) {
strings2[i]=(String)objects[i];
}
System.out.println(Arrays.toString(strings2));
}
2.List
(1)List接口
List: 有序(自然顺序) 有重复 的集合
List常见实现类:
ArrayList: 数组实现 线程 非安全 效率高
LinkedList: - 底层是链表(linked)实现。内部封装一个静态内部类Node
- 双向链表 不存在扩容问题
Vector: 数组实现 线程安全,效率低不建议使用
Stack: Vector的子类 数组实现 遵循先进后出的原则
(2)List使用
public static void main(String[] args) {
List<Integer> lists = new ArrayList<Integer>();
lists.add(23);
lists.add(15);
lists.add(64);
System.out.println(lists);//23 15 64
/*
有序:指自然顺序 ;存储元素的先后顺序 不是排序
*/
lists.add(64);
//可以有重复元素
System.out.println(lists);
}
ArrayList的初始容量和扩容机制
初始容量:10
private static final int DEFAULT_CAPACITY = 10;
扩容机制: 原来容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
ArrayList底层是数组实现,线性结构,更适合查询
3.ArrayList和LinkedList区别
1、数据结构不同
ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。
2、效率不同
当随机访问List(get和set操作)时,ArrayList比LinkedList的效率更高,因为LinkedList是线性的
数据存储方式,所以需要移动指针从前往后依次查找。 当对数据进行增加和删除的操作(add和
remove操作)时,LinkedList比ArrayList的效率更高,因为 ArrayList是数组,所以在其中进行增删
操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
3、自由性不同
ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创
建,然后 添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变
化而变化,但是它不便于使用。
4、主要控件开销不同
ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结
点 信息以及结点指针信息
4.截取子串subList
subList(int fromIndex, int toIndex): 索引为前包后不包
结论:
截取字串操作后,原list也会随之而改变
List和截取后的subList公用一个数据空间资源
5.list与数组之间的转换
集合转化为数组的两种方式:
Object[] toArray()
T[] toArray(T[] a)
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add((int)(Math.random()*100));
}
System.out.println("List中的元素为:" + list);
//1.集合转换为数组的第一种方式
Object[] objects = list.toArray();
System.out.println(Arrays.toString(objects));
//会产生类型转换异常--不建议使用
Integer[] integers = (Integer[]) objects;
System.out.println(Arrays.toString(integers));
//原因一看就知道了,不能将Object[] 转化为String[].转化的话只能是取出每一个元素再转
化,
//1.集合转换为数组的第二种方式--建议使用
Integer[] integers2 = list.toArray(new Integer[list.size()]);
System.out.println(Arrays.toString(integers2));
}
数组转化为集合
Integer[] integers3 = {1,2,3};
List<Integer> list2 = Arrays.asList(integers3);
System.out.println(list2);
//转化后不能对list进行操作,如果操作就会抛出异常
list2.add(4);
6.Stack
Stack:通过栈进行存储 先进后出
常用方法
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
System.out.println(stack);//[1, 2, 3, 4]
System.out.println(stack.pop());//4
System.out.println(stack);//[1, 2, 3]
System.out.println(stack.peek());//3
System.out.println(stack);//[1, 2, 3]
System.out.println(stack.empty());//f
System.out.println(stack.search(1));// 3 返回1这个元素的索引
3.Set
(1)set接口
Set: 无序无重复的集合
Set的常见实现类:
HashSet:底层使用HashMap操作数据
TreeSet:底层封装了TreeMap,对元素可以进行排序,树结构实现
LinkedHashSet:通过链表实现,具有自然顺序的操作
(2)Set测试
(测试无序不重复集合)
测试Set(无序不重复)
public static void main(String[] args) {
Set sets = new HashSet();
sets.add(1); sets.add(-1); sets.add(24); sets.add(13); sets.add(13); sets.add(2); sets.add(3);
System.out.println(sets);//[-1, 1, 2, 3, 24, 13] }
结果为[-1, 1, 2, 3, 24, 13],去除重复元素,且不是按照添加元素顺序输出
测试TreeSet(按自然顺序排列,不重复)
public static void main(String[] args) {
Set sets = new TreeSet(); sets.add(1); sets.add(-1); sets.add(24); sets.add(13); sets.add(13);
sets.add(2); sets.add(3);
System.out.println(sets);//[-1, 1, 2, 3, 13, 24] }
结果为[-1, 1, 2, 3, 13, 24],排序后打印
测试LinkedHashSet(由自己的排序方法排序,不重复)
public static void main(String[] args) {
Set sets = new TreeSet();
sets.add(1); sets.add(-1); sets.add(24); sets.add(13); sets.add(13); sets.add(2); sets.add(3);
System.out.println(sets);//[1, -1, 24, 13, 2, 3] }
结果为[1, -1, 24, 13, 2, 3],按照插入顺序打印