一.集合的概念
1.什么是集合
集合是一种容器, 长度可变, 可以存储任意类型的对象.
基本数据类型也可以装入集合, 但其实内部是先自动装箱成包装类对象, 然后再存入集合的
二.集合的分类
1.Collection
List: 可重复, 有存储顺序,有索引
ArrayList 数组实现, 增删慢, 查找快
LinkedList 链表实现, 增删快, 查找慢
Vector 数组实现, 原理和ArrayList相同, 但线程安全
Set: 不可重复,存取顺序不一致,无索引
HashSet
TreeSet
LinkedHashSet
2.Map
HashMap
TreeMap
Hashtable
LinkedHashMap
三、数组和集合的区别
1,数组既可以存储基本数据类型,也可以存储引用数据类型,存储基本数据类型存储值,存储引用数据类型存储 的是地址值
集合只能存储引用数据类型,也就只能存对象
2,数组的长度一旦初始化就不可以改变
集合的长度是可变的,会随着元素的增多而增长
什么时候用数组,什么时候用集合
元素不变用数组
元素可变用集合
import cn.itcast.bean.Person;
public class Demo1_Collection {
public static void main(String[] args) {
//int[] arr = new int[5];
Person[] arr = new Person[5];
arr = new Person[10];
arr[0] = new Person("张三", 23);
arr[1] = new Person("李四", 24);
System.out.println(arr[2]);
}
}
public class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
四、集合的常用方法
1.常用方法
add(Object obj) 向集合中添加一个元素, 添到最后的位置
get(int index) 获取集合中指定位置的元素
size() 获取集合的长度
add(int index, Object obj) 向集合中添加一个元素, 添到指定位置
set(int index, Object obj) 把集合中指定位置的元素替换
remove(int index) 删除集合中指定位置的元素
remove(Object obj) 删除集合中包含的obj对象(遍历集合中的元素如果传入的元素equals某个元 素就调用remove方法,注意:角标要--)
2迭代集合
a.for循环: 从0循环到集合的size()-1, 每次获取其中一个
b.迭代器: 调用iterator()方法获取迭代器, 使用hasNext()判断是否包含下一个元素, 使用next() 获取下一个元素
c.增强for循环: for(类型 变量名 : 容器) { 循环体 } 容器中有多少个元素就执行多少次循环体, 每次 循环变量指向容器中不同的元素
迭代时删除的问题
a.for循环: 删除时由于后面的元素会向前移动, 所以删除之后循环变量要--
b.迭代器: 要删除元素时必须使用Iterator中的remove()否则会抛出异常
c.增强for循环: 不能删除
1)Collection
public class Demo2_Collection {
/**
* @param args
*/
public static void main(String[] args) {
//demo1();
//demo2();
//demo3();
Collection coll = new ArrayList();
coll.add("a");
coll.add("b");
coll.add("c");
coll.add("d");
coll.add("e");
//System.out.println(coll.isEmpty()); //判断集合是否为空,如果为空就返回true
//coll.clear();
//System.out.println(coll.isEmpty());
System.out.println(coll.remove("a")); //删除,删除成功返回true
System.out.println(coll);
System.out.println(coll.size());
}
private static void demo3() {
Collection coll1 = new ArrayList(); //alt + shift + r 改名
coll1.add("a");
coll1.add("b");
coll1.add("c");
coll1.add("d");
coll1.add("e");
Collection coll2 = new ArrayList(); //alt + shift + r 改名
coll2.add("a");
coll2.add("b");
coll2.add("c"); //alt + 上下键向上或向下移动
coll2.add("d");
coll2.add("e");
System.out.println(coll1.equals(coll2));//判断两个集合中的元素是否一样,顺序也要一致
}
private static void demo2() {
Collection coll = new ArrayList();
coll.add("a");
coll.add("b");
coll.add("c");
coll.add("d");
coll.add("e");
//System.out.println(coll);
//coll.clear(); //清空集合中的元素
//System.out.println(coll);
System.out.println(coll.contains("b")); //判断是否包含
System.out.println(coll.contains("z")); //alt + ctrl + 下键 向下复制一行
}
private static void demo1() {
Collection coll = new ArrayList();
boolean b1 = coll.add(1); //Object obj = new Integer(1);
boolean b2 = coll.add("a");
boolean b3 = coll.add(true);
boolean b4 = coll.add(1);
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(b4);
System.out.println(coll.toString());
}
}
* 接口没有继承Object,因接口中所有的方法都是抽象的,那么为什么接口可以调用Object中的方法呢?
* 因为jvm同映射拿到Object中的方法
public static void main(String[] args) {
Inter i = new Demo();
i.print();
}
}
interface Inter {
public void print();
}
class Demo implements Inter {
public void print() {
System.out.println("111111111111");
2)List
public class Demo5_List {
public static void main(String[] args) {
//demo1();
//demo2();
//demo3();
//demo4();
//demo5();
//demo6();
//demo7();
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
list.add("g");
List newList = list.subList(1, 4); //截取子集合
System.out.println(list);
System.out.println(newList);
}
private static void demo7() {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.set(1, "z");
System.out.println(list); //修改指定位置的元素
}
private static void demo6() {
List list = new ArrayList();
list.add(111);
list.add(222);
list.add(333);
list.remove(new Integer(111));//删除Integer对象的时候,不会自动装需要手动装箱
System.out.println(list);
}
private static void demo5() {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
Object obj = list.remove(1)//根据指定索引删除,返回被删除的元素
boolean b = list.remove("c");
System.out.println(obj);
System.out.println(b);
System.out.println(list);
}
private static void demo4() {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
int index1 = list.indexOf("a"); //在集合中查找对象(从前向后找),返回的是对象的索引
System.out.println(index1);
int index2 = list.lastIndexOf("a");//在集合中查对象对象(从后向前找),返回的是对象的索引
System.out.println(index2);
}
private static void demo3() {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
//Object obj = list.get(2);
//System.out.println(obj);
for(int i = 0;i < list.size(); i++) { //List集合中的第一种迭代
System.out.println(list.get(i));
}
}
private static void demo2() {
List list1 = new ArrayList();
list1.add("a");
list1.add("b");
list1.add("c");
list1.add("d");
List list2 = new ArrayList();
list2.add("a");
list2.add("b");
list2.add("c");
list2.add("d");
list1.addAll(2, list2); //在指定位置添加一个集合进来
System.out.println(list1);
}
private static void demo1() {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
//list.add(1, "z");//在指定位置添加,index <= size && index >= 0,否则IndexOutOfBoundsException
list.add(4, "z");
System.out.println(list);
}
}
3)List的三个儿子(掌握)
(1)List的三个儿子特点:
List
|--ArrayList
底层数据结构是数组,查询和修改快,增删慢
线程不安全,效率高
|--Vector
底层数据结构是数组,查询慢(相对应ArrayList),增删慢(相对应LinkedList)
线程安全,效率低
|--LinkedList
底层数据结构是链表,查询和修改慢,增删快
线程不安全,效率高
(2)ArrayList(存储字符串和自定义对象)
(3)Vector(存储字符串和自定义对象)
有自己的特殊功能。
但是不用,被新功能给替代了。
(4)LinkedList(存储字符串和自定义对象)
有自己的特殊功能。可以很方便的操作头和尾。
(5)案例:
A:ArrayList存储字符串并去除重复值
B:ArrayList存储自定义对象并去除重复值
需求:我们认为同姓名和同年龄的人即为同一个人。
C:用LinkedList模拟栈数据结构
public class Demo7_Delete {
public static void main(String[] args) {
//demo1();
ArrayList list = new ArrayList();
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");
/*for(int i = 0; i < list.size(); i++) { //普通for循环可以删除,删除的时候索引要--
Object obj = list.get(i);
if(obj.equals("a")) {
list.remove(i--);
}
}*/
/*Iterator it = list.iterator();
while(it.hasNext()) { //迭代可以删除,但是必须用迭代器的删除方法
Object obj = it.next(); //如果用集合的删除方法,会出现并发修改异常ConcurrentModificationException
if(obj.equals("b")) {
//list.remove("b");
it.remove();
}
}*/
for (Object obj : list) { //增强for循环不能删除
if(obj.equals("b")) {
list.remove("b");
}
}
System.out.println(list);
}
private static void demo1() {
ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
for(int i = 0; i < list.size(); i++) { //如果需要使用索引就用普通for循环
System.out.println(list.get(i));
}
Iterator it = list.iterator(); //不需要索引可以用迭代器
while(it.hasNext()) {
System.out.println(it.next());
}
for (Object obj : list) { //代码简单,只要能用迭代迭代的就可以用增强for循环
System.out.println(obj);
}
}
}
Vector和ArrayList的区别
* 共同点:Vector和ArrayList的底层都是用数组实现的
* 区别:
* Vector是jdk1.0版本的出现的,是线程安全的,效率低
* ArrayList是jdk1.2版本出现的,是线程不安全的,效率高
* 特有迭代器 : 枚举
public class Demo2_Vector {
/**
* @param args
*/
public static void main(String[] args) {
Vector v = new Vector();
v.addElement("a");
v.addElement("b");
v.addElement("c");
v.addElement("d");
Enumeration en = v.elements();
while(en.hasMoreElements()) {
System.out.println(en.nextElement());
}
Vector v2 = new Vector();
v2.add("a");
v2.add("b");
v2.add("c");
v2.add("d");
Iterator it = v2.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
LinkedList
ArrayList和LinkedList的区别
* ArrayList底层是数组实现的,查找和修改比较快,增和删比较慢
* LinkedList底层是链表实现的,查找和修改比较慢,增和删比较快
*/
public class Demo3_LinkedList {
/**
* @param args
*/
public static void main(String[] args) {
//demo1();
LinkedList list = new LinkedList();
/*list.add("a");
list.add("b");
list.add("c");
list.add("d");*/
// System.out.println(list.getFirst()); //当集合中没有元素,抛出元素找不到异常,后续代码不会执行
// System.out.println(list.getLast());
// System.out.println(list.peekFirst()); //当集合中没有元素,返回null,后续代码继续执行
// System.out.println(list.peekLast());
System.out.println(list.removeFirst()); //删除第一个元素
// System.out.println(list.removeLast()); //删除最后一个元素
// System.out.println(list.pollFirst());
// System.out.println(list.pollLast());
System.out.println("111111111111111111111111111");
}
private static void demo1() { //ctrl + d 删除选中部分
LinkedList list = new LinkedList();
list.addFirst("a"); //在集合的第一个位置添加
list.addFirst("b");
list.addFirst("c");
list.addFirst("d");
list.addLast("e"); //在集合的最后一个位置添加
System.out.println(list);
}
}
五、总结
2、ArrayList和LinkedList的区别
ArrayList底层是数组实现的,查找和修改比较快,增和删比较慢
LinkedList底层是链表实现的,查找和修改比较慢,增和删比较快
3、Vector和ArrayList的区别
* 共同点:Vector和ArrayList的底层都是用数组实现的
* 区别:
* Vector是jdk1.0版本的出现的,是线程安全的,效率低
* ArrayList是jdk1.2版本出现的,是线程不安全的,效率高,
* 特有迭代器 枚举