集合与数组的区别
数组和集合类都是容器
数组长度是固定的,集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象数组中存储数据类型是单一的,集合中可以存储任意类型的对象。
集合类的特点
用于存储对象,长度是可变的,可以存储不同类型的对象。
集合的储存方式: https://blog.csdn.net/qq_39291929/article/details/81351026
图解:https://www.cnblogs.com/jiqing9006/p/7615467.html
数组和链表存储方式
数组:有索引和data两部分组成
链表:是有data和指向下一个数据的指针地址两部分组成
Vector、ArrayList都是以数组的形式存储在内存中,所以查询效率高,新增和删除效率不高,但是Vector被Synchronized修饰,所以线程是安全的,ArraryList线程不安全。
LinkedList则以链表的形式进行存储,所以查询效率底,新增和删除效率高,并且线程不安全。
集合的分布
---|Collection: 单列集合
---|List: 有存储顺序, 可重复
---|ArrayList: 数组实现, 查找快, 增删慢
由于是数组实现, 在增和删的时候会牵扯到数组
增容, 以及拷贝元素. 所以慢。数组是可以直接
按索引查找, 所以查找时较快
---|LinkedList: 链表实现, 增删快, 查找慢
由于链表实现, 增加时只要让前一个元素记住自
己就可以, 删除时让前一个元素记住后一个元
素, 后一个元素记住前一个元素. 这样的增删效
率较高但查询时需要一个一个的遍历, 所以效率
较低
---|Vector: 和ArrayList原理相同, 但线程安全, 效率略低
和ArrayList实现方式相同, 但考虑了线程安全问
题, 所以效率略低
性能:ArrayList = LinkedList > Vector
---|Set: 无存储顺序, 不可重复
---|HashSet 内容无序 不可重复 支持null
---|TreeSet 内按字典序 不可重复 不支持null
---|LinkedHashSet 带存储顺序 不可重复
性能:HashSet > TreeSet > LinkedHashSet
---| Map: 键值对 (key,value) key的特点是无序的,不可以重复的,通过唯一的key拿到唯一的value。
---|HashMap 非线程安全,高效,key无序 key支持null
---|TreeMap key按按字典序 key不支持null
---|HashTable 线程安全,低效,key支持null
---|LinkedHashMap
性能 : HashMap > TreeMap > LinkedHashMap > HashTable
Collection接口
Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。
Collection的接口方法有:list集合和set集合都会有以下的方法
方法 | 内容 |
---|---|
add() | 将指定对象存储到容器中 |
addAll() | 将指定集合中的元素添加到调用该方法和集合中 |
remove() | 将指定的对象从集合中删除 |
removeAll() | 将指定集合中的元素删除 |
clear() | 清空集合中的所有元素 |
isEmpty() | 判断集合是否为空 |
contains() | 判断集合何中是否包含指定对象 |
containsAll() | 判断集合中是否包含指定集合 |
int size() | 返回集合容器的大小 |
toArray() | 集合转换数组 |
List系列
ArrayList 数组实现, 查找快, 增删慢
方法 | 内容 |
---|---|
E get(int index) | 返回此列表中指定位置的元素。 |
int size() | 返回此列表中元素的数目。 |
Iterator iterator() | 在这个列表中的元素上返回一个正确的顺序。 |
//遍历方式 增强的for循环
for (String string : list) {
System.out.println(string);
}
//索引的方式 因为是数组的方式存储方式,所以索引从0开始
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//利用迭代器的方法
Iterator<String> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
// 1.由于Collection是接口所以需要其子接口的子类来完成对集合的实例
List<String> list = new ArrayList<String>();
list.add("s1");
list.add("s2");
list.add("s6");
System.out.println("------2--------");
// 2.遍历方式 增强的for循环
for (String string : list) {
System.out.println(string);
}
System.out.println("------3--------");
// 3.索引的方式 因为是数组的方式存储方式,所以索引从0开始
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("------4--------");
// 4.利用迭代器的方法
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("------5--------");
// 5.集合添加 将新建的list2内容添加到list,遍历的时候可以到一集修改
List<String> list2 = new ArrayList<String>();
String str = new String("s3");
list2.add(new String("s3"));
list2.add(new String("s3"));
list2.add("s4");
list.addAll(list2);
for (String string : list) {
System.out.println(string);
}
// 6.如果集合的类型不同,那么无法进行集合之间的添加元素
// List<Integer> list3 = new ArrayList<Integer>();
// list3.add(1);
// list3.add(222);
// list.addAll(list3);
System.out.println("------7--------");
// 7.删除集合里面的对应对象
// 根据索引删除第二个值
list.remove(1);
// 根据对应的值来删除,如果有重复对象,那么就删除一个对象
list.remove("s3");
// 根据某个集合的参考,来删除
list.removeAll(list2);
List<String> list3 = new ArrayList<String>();
list3.add(new String("s6"));
for (String string : list) {
System.out.println(string + ":" + string.hashCode());
}
// list.removeAll(list3);
// list.remove(new String("s6").hashCode());
System.out.println(new String("s6").hashCode());
for (String string : list) {
System.out.println(string);
}
System.out.println("--------8---------");
// 8.清空集合所有元素
list.clear();
// 判断集合是否为空
System.out.println(list.isEmpty());
// 这个时候判断它的大小,是0
System.out.println(list.size());
for (String string : list) {
System.out.println(string);
}
System.out.println("--------9---------");
// 9.判断集合何中是否包含指定对象
System.out.println(list3.contains("s6"));
// 10.toArray() 推荐使用第二种方式,类型可以转化,但是第一种方式值能作为Object
Object[] strArray1 = list.toArray();
String[] strArray2 = list3.toArray(new String[list3.size()]);
for (String string : strArray2) {
System.out.println(string);
}
LinkedList :链表实现, 增删快, 查找慢
/*
* 学习Java中三种长度表现形式
* 数组.length 属性 返回值 int
* 字符串.length() 方法,返回值int
* 集合.size()方法, 返回值int
*/
Set
无存储顺序, 不可重复
—|HashSet 内容无序 不可重复 支持null
—|TreeSet 内按字典序 不可重复 不支持null
—|LinkedHashSet 带存储顺序 不可重复
Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中
Set没有索引的方式去获取对应的元素
保证元素唯一性的方式依赖于:hashCode()与equals()方法。
方法 | 内容 |
---|---|
add( ) | 向集合中添加元素 |
clear( ) | 去掉集合中所有的元素 |
contains( ) | 判断集合中是否包含某一个元素 |
isEmpty( ) | 判断集合是否为空 |
iterator( ) | 主要用于递归集合,返回一个Iterator()对象 |
remove( ) | 从集合中去掉特定的对象 |
size( ) | 返回集合的大小 |
Test1:
public class Test1 {
public static void main(String[] args) {
// 集合的分布
// Collection--单列集合
// List //有序可以重复
// ArrayList//数组实现, 查找快, 增删慢,线程不安全的
// LinkedList//Linked:链表//链表实现, 增删快, 查找慢
// Vector//数组实现, 查找快, 增删慢,线程安全的,因为线程安全肯定会比ArrayList慢,有得必有失
// 性能:ArrayList = LinkedList > Vector
List list = new ArrayList();
list.add("123");// 往集合中塞东西
list.add("456");
list.add("789");
System.out.println(list.get(1));// 下标
// 怎么迭代,可以有2种,一种是for循环、一种是foreach循环
for (int i = 0; i < list.size(); i++) {// list.size()获取集合长度
System.out.println(list.get(i));
}
for (Object object : list) {
System.out.println(object);
}
List list2 = new LinkedList();
list2.add("987");
list2.add("654");
list2.add("321");
System.out.println(list2.get(1));
for (Object object : list2) {
System.out.println(object);
}
List list3 = new Vector();
list3.add("741");
list3.add("852");
list3.add("963");
System.out.println(list3.get(1));
// Set //无序的不可重复的
// Map--key,value(键值对)
}
}
Test2:
public class Test2 {
public static void main(String[] args) {
// 集合的分布
// Collection--单列集合
// List //有序可以重复
// ArrayList//数组实现, 查找快, 增删慢,线程不安全的
// LinkedList//Linked:链表//链表实现, 增删快, 查找慢
// Vector//数组实现, 查找快, 增删慢,线程安全的,因为线程安全肯定会比ArrayList慢,有得必有失
// 性能:ArrayList = LinkedList > Vector
// Set //无序的不可重复的
// HashSet//内容无序 不可重复 支持null
// TreeSet//内按字典序 不可重复 不支持null
// LinkedHashSet//带存储顺序 不可重复
Set set = new HashSet();// set集合是没有下标的
set.add("123");
set.add("456");
set.add("789");
set.add(null);
set.add("456");
set.add("456");
set.add("456");
// set要拿到里面的内容,我们需要迭代数据
// set集合应该使用那个循环迭代呢for,还是foreach/iterator
for (Object object : set) {
System.out.println(object);
}
// iterator迭代器,可以使用迭代器迭代set集合
Iterator iterator = set.iterator();// 获取set集合的迭代器
// iterator.hasNext();// 询问是有还有下一个数据
while (iterator.hasNext()) {
Object object = iterator.next();
System.out.println(object);
}
System.out.println("--------------------------------------------------");
Set set2 = new TreeSet();// 内按字典序 不可重复 不支持null
set2.add("987");
set2.add("654");
set2.add("321");
set2.add("987");
set2.add("987");
set2.add("987");
set2.add("654");
set2.add("321");
// set2.add(null);//编译是可以通过的,可是会有运行时异常NullPointerException
for (Object object : set2) {
System.out.println(object);
}
// 字典序就是排序的意思 1-9 a-z ,先比较第一位 ,如果第一位比较不出来的,就比较第二位
// "112"
// "123"
// "456"
// "789"
// "aab"
// "abc"
// "ccc"
System.out.println("--------------------------------------------------");
Set set3 = new TreeSet();
set3.add("112");
set3.add("789");
set3.add("123");
set3.add("aab");
set3.add("456");
set3.add("ccc");
set3.add("abc");
for (Object object : set3) {
System.out.println(object);
}
Set set4 = Collections.synchronizedSet(set3);
set4.remove("abc");
// Map--key,value(键值对)
}
}
Test3:
public class Test1 {
public static void main(String[] args) {
List list = new ArrayList();// 集合中不能存放基本类型
// 没有泛型的默认是object类型,如果规范了类型之后,就要按照规范的类型来填写
list.add("123");// 只要带双引号的都是String
list.add(456);// Integer, 自动装箱,自动拆箱
list.add(456.02);// Double
for (Object object : list) {
System.out.println(object);
}
System.out.println("-----------------------------------------");
// index:下标
list.remove(2);
for (Object object : list) {
System.out.println(object);
}
System.out.println("-----------------------------------------");
list.clear();// 清空集合
for (Object object : list) {
System.out.println(object);
}
System.out.println("-----------------------------------------");
System.out.println(list.isEmpty());
System.out.println("-----------------------------------------");
List list2 = new ArrayList();// 集合中不能存放基本类型
// 没有泛型的默认是object类型,如果规范了类型之后,就要按照规范的类型来填写
list2.add("123");// 只要带双引号的都是String
list2.add(456);// Integer, 自动装箱,自动拆箱
list2.add(456.02);// Double
System.out.println(list2.contains(123));// 判断集合何中是否包含指定对象,有就返回true ,没有就false
list2.size();// 获取集合长度的
Object[] objects = list2.toArray();// 集合转数组
// 数组转集合呢
List list3 = Arrays.asList(objects);
// add()将指定对象存储到容器中
// remove()将指定的对象从集合中删除
// clear()清空集合中的所有元素
// isEmpty()判断集合是否为空
// contains()判断集合何中是否包含指定对象
// int size()返回集合容器的大小
// toArray()集合转换数组
List list4 = new ArrayList();// 只有4个元素
list4.add(1);
list4.add(2);
list4.add(3);
list4.add(4);
List list5 = new ArrayList();
list5.add(3);
list5.add(3);
list5.add(3);
list5.add(4);
// System.out.println(list4.addAll(list5));// 就会把list5的元素追加到list4中,所以现在的list4,一共有8个元素
// System.out.println(list4.size());
// addAll()将指定集合中的元素添加到调用该方法和集合中
// removeAll()将指定集合中的元素删除
// list4.removeAll(list5);// 如果list5中有的元素,在list4中移除掉,现在就剩下多少个元素
// System.out.println(list4.size());// 2
// containsAll()判断集合中是否包含指定集合
System.out.println(list4.containsAll(list5));
}
}
Test4:
public class Test2 {
public static void main(String[] args) {
// 去除重复数据
// 可以使用set集合,有一个特点就是不可重复的
// 那如果List 集合 addAll 到 Set 集合中会 怎么样? 会不会被Set集合自动处理掉那些重复的?会
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(4);
list.add(5);
list.add(1);
Set set = new HashSet();// 无序不可重复的
set.add(1);
set.add(6);
set.add(7);
set.add(5);
set.addAll(list);// 有多少个长度
System.out.println(set.size());
System.out.println("----------------------------------------");
for (Object object : set) {
System.out.println(object);
}
}
}