集合由来:
数组长度是固定的,当添加的元素长度超过数组长度时需重新定义数组
因此java内部提供了集合类,可存储任意对象,长度也可以改变,随元素的增减而增减
集合、数组区别:
- 数组:可存储基本数据类型(存储的是值),也可存储引用数据类型(存储的是地址值);长度固定不可变
- 集合:只能存储引用数据类型(即对象),可存储基本数据类型,存储时自动装箱成对象;长度可变,随元素增减
使用场合:
- 数组:元素个数固定,则使用数组
- 集合:元素个数不固定,则使用集合
例子
- 公共实体类
package cn.chen.demo;
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
= name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
super();
= name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}- 简单数组
package cn.chen.demo;
public class Demo_Simple {
public static void main(String[] args) {
demo1();
demo2();
}
private static void demo1() {
int[] arr = new int[3];//创建基本数据类型数组
arr[0] = 3;
arr[1] = 4;
arr[2] = 2;
System.out.print("基本数据类型数组:");
for(int i =0 ;i<arr.length;i++){
System.out.print(arr[i]+",");
}
System.out.println();
}
private static void demo2() {
Person[] p = new Person[3];//创建引用数据类型数组
p[0]=new Person("张三",21);
p[1]=new Person("李四",20);
p[2]=new Person("王五",20);
System.out.print("引用数据类型数组:");
for(int i = 0 ;i<p.length;i++){
System.out.print(p[i]+ ",");
}
System.out.println();
}
}
运行结果:
基本数据类型数组:3,4,2,
引用数据类型数组:Person [name=张三, age=21],Person [name=李四, age=20],Person [name=王五, age=20],- Collection
package cn.chen.demo;
import java.util.ArrayList;
import java.util.Collection;
/**
* collectionXxx.java使用了未经检查或不安全的操作.
注意:要了解详细信息,请使用 -Xlint:unchecked重新编译.java编译器认为该程序存在安全隐患
温馨提示:这不是编译失败,可以先不用理会,学了泛型就理解了
add方法:如果是List集合一直都返回true,因为List集合中是可以存储重复元素的;如果是Set集合当存储重复元素的时候,就会返回false
ArrayList的父类的父类重写toString方法,所以在打印对象的引用的时候,输出的结果不是Object类中toString的结果
* 方法
boolean add(E e) //添加元素
int size() //集合长度
boolean remove(Object o) //删除指定元素
boolean contains(Object o) //判断是否包含该元素
boolean isEmpty() //判断集合是否为空
void clear() //清空集合
*/
public class Demo_Collection {
public static void main(String[] args) {
col1();
}
private static void col1() {
Collection c =new ArrayList();
c.add("1");
c.add("2");
c.add("3");
c.add("4");
c.add("5");
System.out.println("集合长度(元素个数):"+c.size());//集合长度
System.out.println("集合元素:"+c);
c.remove("4");//移除指定元素
System.out.println("------------ remove后 ----------");
System.out.println("集合长度(元素个数):"+c.size());
System.out.println("集合元素:"+c);
System.out.println("------------ 判断是否包含 ----------");
System.out.println("不包含:"+c.contains("4"));//判断是否包含该元素
System.out.println("包含:"+c.contains("3"));
System.out.println("------------ 判断集合是否为空 ----------");
System.out.println("不为空:"+c.isEmpty());
c.clear();//清空集合
System.out.println("------------ clear后 ----------");
System.out.println("集合长度(元素个数):"+c.size());
System.out.println("------------ 判断集合是否为空 ----------");
System.out.println("为空:"+c.isEmpty());
}
}带ALL功能
package cn.chen.demo;
import java.util.ArrayList;
import java.util.Collection;
public class Demo_Collection_2 {
/**带All的功能
boolean addAll(Collection c) // 将c2中的每一个元素添加到c1中
boolean removeAll(Collection c) //删除交集
boolean containsAll(Collection c) //判断调用的集合是否包含传入的集合
boolean retainAll(Collection c) //判断是否是交集
*/
public static void main(String[] args) {
demo1();
demo2();
demo3();
demo4();
}
private static void demo1() {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("1");
c1.add("2");
c1.add("3");
c2.add("2");
c2.add("4");
boolean c = c1.containsAll(c2);//判断调用的集合是否包含传入的集合
System.out.println("判断是否包含:"+c);
}
private static void demo2() {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("1");
c1.add("2");
c1.add("3");
//c2.add(c1); //输出结果为 [[1, 2, 3]] 这里是将整个c1当成一个对象添加到c2中去
c2.addAll(c1); //输出结果为 [1, 2, 3] 这里是将c1的每一个元素都添加到c2中去
System.out.println("c2集合元素:"+c2);
}
private static void demo3() {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("1");
c1.add("2");
c1.add("3");
c2.add("2");
c1.removeAll(c2);//删除交集
System.out.println("删除交集之后结果:"+c1);
}
private static void demo4() {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("1");
c1.add("2");
c1.add("3");
c2.add("2");
c2.add("4");
boolean b = c1.retainAll(c2);//判断是否是交集
System.out.println("判断是否存在交集:"+b+",取交集:"+c1);
}
}
运行结果:
判断是否包含:false
c2集合元素:[1, 2, 3]
删除交集之后结果:[1, 3]
判断是否存在交集:true,取交集:[2]集合转数组
package cn.chen.demo;
import java.util.ArrayList;
import java.util.Collection;
public class Demo_Collection_3 {
//集合转数组
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(new Person("张三",12));
c.add(new Person("李四",15));
c.add(new Person("王五",17));
Object[] o = c.toArray();//集合转换成数组
for(int i=0;i<c.size();i++){
Person p = (Person) o[i];//向下转型,将Object强转为Person类型
System.out.println(p.getName()+","+p.getAge());
}
}
}
运行结果:
张三,12
李四,15
王五,17迭代器
原理:迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可
package cn.chen.demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo_Collection_4 {
public static void main(String[] args) {
demo1();
demo2();
}
private static void demo1() {
Collection c = new ArrayList();
c.add(new Person("张三",34));
c.add(new Person("李四",28));
c.add(new Person("王五",26));
c.add(new Person("赵六",32));
Iterator it = c.iterator();//获取迭代器
//对集合中的元素迭代(遍历)
while(it.hasNext()){//判断集合中是否有元素,有就返回true
System.out.println(it.next());
}
}
private static void demo2() {
Collection c = new ArrayList();
c.add(new Person("张三",34));
c.add(new Person("李四",28));
c.add(new Person("王五",26));
c.add(new Person("赵六",32));
Iterator it = c.iterator();//获取迭代器
while(it.hasNext()){//判断集合中是否有元素,有就返回true
Person p =(Person) it.next();//向下转型
System.out.println(p.getName()+","+p.getAge());
}
}
}
运行结果:
Person [name=张三, age=34]
Person [name=李四, age=28]
Person [name=王五, age=26]
Person [name=赵六, age=32]
张三,34
李四,28
王五,26
赵六,32- List
package cn.chen.demo;
import java.util.ArrayList;
import java.util.List;
public class Demo_List_1 {
/**
* void add(int index,E element)
E remove(int index)
E get(int index)
E set(int index,E element)
*/
// index<=size并且index>=0都不会报异常
// java.lang.IndexOutOfBoundsException,当存储时使用不存在的索引时
public static void main(String[] args) {
List l = new ArrayList();
l.add("1");//添加元素
l.add("2");
l.add("3");
l.add("4");
l.add("5");
System.out.println("数组:"+l);
Object o = l.remove(1);//根据索引删除元素
System.out.println("被删除元素:"+ o +",删除指定索引后数组:"+l);
l.set(1, "8");//根据索引修改元素
System.out.println("修改指定索引后数组:"+l);
System.out.print("遍历数组:");
//通过索引遍历List集合
for(int i = 0; i<l.size();i++){
System.out.print(l.get(i)+" ");//取元素
}
}
}
运行结果:
数组:[1, 2, 3, 4, 5]
被删除元素:2,删除指定索引后数组:[1, 3, 4, 5]
修改指定索引后数组:[1, 8, 4, 5]
遍历数组:1 8 4 5- Iterator和ListIterator
迭代器修改元素(ListIterator的特有功能add)
package cn.chen.demo.iterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class Demo_Iterator_1 {
public static void main(String[] args) {
List l = new ArrayList();
l.add("陈陈");
l.add("沉沉");
l.add("辰辰");
l.add("尘尘");
l.add("臣臣");
demo(l);
}
private static void demo(List l) {
ListIterator li = l.listIterator();//获取迭代器(List集合特有的)
while(li.hasNext()){
String str = (String) li.next();
if("沉沉".equals(str)){
li.add("小北");// //遍历的同时在增加元素,并发修改java.util.ConcurrentModificationException
}
}
System.out.println("ListIterator:"+l);
}
}
运行结果:
ListIterator:[陈陈, 沉沉, 小北, 辰辰, 尘尘, 臣臣]ListIterator 向前移、向后移(向前移情况下,必须是先向后移,前面有元素才有用)
package cn.chen.demo.iterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class Demo_Iterator_2 {
public static void main(String[] args) {
List l = new ArrayList();
l.add("陈陈");
l.add("沉沉");
l.add("辰辰");
l.add("尘尘");
l.add("臣臣");
ListIterator li = l.listIterator();
System.out.print("获取元素且将指针向后移:");
while(li.hasNext()){
System.out.print(li.next()+",");
}
System.out.println();
System.out.print("获取元素且将指针向前移:");
while(li.hasPrevious()){
System.out.print(li.previous()+",");
}
}
}
运行结果:
获取元素且将指针向后移:陈陈,沉沉,辰辰,尘尘,臣臣,
获取元素且将指针向前移:臣臣,尘尘,辰辰,沉沉,陈陈,- A:数组
- 查询快修改也快
- 增删慢
- B:链表
- 查询慢,修改也慢
- 增删快
- List的三个子类特点
- ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。 - Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构) - LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
- 区别
- Vector和ArrayList的区别
Vector是线程安全的,效率低
ArrayList是线程不安全的,效率高
共同点:都是数组实现的 - ArrayList和LinkedList的区别
ArrayList底层是数组结果,查询和修改快
LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
共同点:都是线程不安全的
- 使用场合
- 查询多用ArrayList
- 增删多用LinkedList
- 如果都多ArrayList
- foreach
增强for:简化数组和Collection集合的遍历
格式:
for(元素数据类型 变量 : 数组或者Collection集合) {
使用变量即可,该变量就是元素
}好处:简化遍历
增强for循环底层依赖的是迭代器(Iterator)
- set
TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。它继承于AbstractSet抽象类,实现了NavigableSet,Cloneable,java.io.Serializable接口。
package cn.chen.demo;
import java.util.TreeSet;
public class Demo_TreeSet {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(12);
ts.add(14);
ts.add(43);
ts.add(27);
ts.add(32);
System.out.println(ts);
}
}
运行结果:
[12, 14, 27, 32, 43]三者比较:
1.List
a. 普通for循环, 使用 get() 逐个获取
b. 调用 iterator() 方法得到 Iterator, 使用 hasNext() 和 next() 方法
c. 增强for循环, 只要可以使用 Iterator 的类都可以用
d. Vector 集合可以使用 Enumeration 的 hasMoreElements() 和 nextElement() 方法
2.Set
a. 调用 iterator() 方法得到 Iterator , 使用 hasNext() 和 next() 方法
b. 增强for循环, 只要可以使用 Iterator 的类都可以用
3.普通for循环,迭代器,增强for循环是否可以在遍历的过程中删除
a. 普通for循环:可以删除,但是索引要 – (减减)
b. 迭代器:可以删除,但是必须使用迭代器自身的 remove 方法,否则会出现并发修改异常
c. 增强for循环:不能删除
- Map
概述:
- 将键映射到值的对象
- 一个映射不能包含重复的键
- 每个键最多只能映射到一个值
Map接口和Collection接口的不同:
- Map是双列的, Collection是单列的
- Map的键唯一, Collection的子体系Set是唯一的
- Map集合的数据结构值针对键有效,跟值无关; Collection集合的数据结构是针对元素有效
Map集合的功能概述
- a:添加功能
- V put(K key,V value):添加元素。
- 如果键是第一次存储,就直接存储元素,返回null
- 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
- b:删除功能
- void clear():移除所有的键值对元素
- V remove(Object key):根据键删除键值对元素,并把值返回
- c:判断功能
- boolean containsKey(Object key):判断集合是否包含指定的键
- boolean containsValue(Object value):判断集合是否包含指定的值
- boolean isEmpty():判断集合是否为空
- d:获取功能
- Set
















