一、集合框架
1.数组和集合都是容器,两者有什么区别呢?
数组长度是固定的,数组可以存储对象,可以存储基本数据类型。
集合长度是可变的,集合只能存储对象。
2.为什么出现这么多容器呢?
因为每一个容器对数据的存储方式不一样,这个存储方式被称为数据结构。
二、常用方法
2.1 增加、删除
import java.util.*; /* 1,add方法的参数类型是Object。以便接收任意类型对象。 2,集合中存储的都是对象的引用(地址)。 */ public class CollectionTest { public static void main(String[] args) { //创建一个集合容器,使用Collection接口的子类:Arraylist。 ArrayList<String> al = new ArrayList<String>(); //1.添加元素 al.add("java01"); //add(Object o); al.add("java02"); al.add("java03"); al.add("java04"); //2.获取个数。集合长度。 System.out.println("size:"+al.size()); //3.删除元素。 al.remove("java01"); //al.clear(); //4.判断元素 System.out.println("java03是否存在:" + al.contains("java03")); System.out.println("al是否为空:" + al.isEmpty()); //打印集合。 System.out.println(al); } } 运行结果: size:4 java03是否存在:true al是否为空:false [java02, java03, java04]
2.2 取交集、差集
public static void method1() { ArrayList<String> al1 = new ArrayList<String>(); al1.add("java01"); al1.add("java02"); al1.add("java03"); al1.add("java04"); ArrayList<String> al2 = new ArrayList<String>(); al2.add("java01"); al2.add("java02"); al2.add("java07"); al2.add("java08"); // al1.retainAll(al2); //取交集,al1中只会保留与al2中相同的元素。 // System.out.println(al1); // System.out.println(al2); al1.removeAll(al2); System.out.println(al1); System.out.println(al2); } retainAll运行结果: [java01, java02] [java01, java02, java07, java08] removeAll运行结果: [java03, java04] [java01, java02, java07, java08]
2.3 元素的取出
public void get_method() { ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add("java04"); Iterator it = al.iterator(); //迭代器 while(it.hasNext()) { System.out.println(it.next()); } } 运行结果: java01 java02 java03 java04
或者也可以这样写:
for(Iterator it = al.iterator();it.hasNext();) { System.out.println(it.next()); }
三、List
3.1 list常见操作
package com.collection; /* * Collection * |--List:元素有序。元素可以重复。因为该集合体系有索引。 * |--Set:元素无序。元素不可以重复。 * * List: * 特有方法:凡是可以操作角标的方法都是该体系特有的方法。 * * 增: * add(index,element); * addAll(index,Collection); * 删: * remove(index); * 改: * set(index,element); * 查: * get(index); * subList(from,to); * listIterator(); * */ import java.util.*; public class ListDemo { public static void main(String[] args) { ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); System.out.println("原集合是:"+al); //原集合是:[java01, java02, java03] //在指定位置添加元素 al.add(1, "java8"); System.out.println("在指定位置添加元素后:"+al); //在指定位置添加元素后:[java01, java8, java02, java03] //删除指定位置的元素 al.remove(2); System.out.println("删除指定位置的元素后:"+al); //删除指定位置的元素后:[java01, java8, java03] //修改元素 al.set(1, "java007"); al.add("java009"); al.add("java009"); al.add("java009"); System.out.println("修改元素后:"+al); //修改元素后:[java01, java007, java03, java009, java009, java009] //通过角标获取元素 System.out.println("获取元素:"+al.get(1)); //获取元素:java007 //获取所有元素 for(int i=0; i<al.size();i++) { System.out.println("al("+i+"):"+al.get(i)); } //通过迭代器获取所有元素 for(Iterator it = al.iterator();it.hasNext();) { System.out.println(it.next()); } //通过indexof获取对象位置 System.out.println(al.indexOf("java007")); //1 System.out.println(al.lastIndexOf("java009")); //5 List sub = al.subList(1, 4); // 包括开始,不包括结尾 System.out.println("subList = " + sub); //subList = [java007, java03, java009] } }
3.2 列表迭代器
import java.util.*; public class ListDemo { public static void main(String[] args) { //演示列表迭代器 ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); Iterator it = al.iterator(); // while(it.hasNext()){ // System.out.println(it.next()); // } //在迭代过程中准备添加或者删除元素 while(it.hasNext()){ Object obj = it.next(); if(obj.equals("java02")) al.add("java000"); System.out.println("obj = " + obj); } } } 运行结果: Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at com.collection.ListDemo.main(ListDemo.java:44) obj = java01 obj = java02 并发修改异常。 在用迭代器操作时,又用了集合的操作。
3.2.1 使用迭代器操作(局限性:只能删除)
//在迭代过程中准备添加或者删除元素 while(it.hasNext()){ Object obj = it.next(); if(obj.equals("java02")) it.remove(); //将java02的引用从集合中删除 System.out.println("obj = " + obj); } System.out.println(al); 运行结果: obj = java01 obj = java02 obj = java03 [java01, java03]
3.2.2 ListIterator
/* * List集合特有的迭代器:ListIterator。 * ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素。 * 因为会发生ConcurrentModificationException异常。 * * 所以,在迭代时,只能使用迭代器的方法操作元素。 * 可是Iterator方法有限,只能对元素进行判断、取出、删除的操作。 * 如果想要其他操作,比如添加、修改等,就需要使用其子接口,ListIterator。 * * 该接口只能通过List集合的listIterator()方法调用。 * */ public static void main(String[] args) { //演示列表迭代器 ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add("java008"); ListIterator li = al.listIterator(); while(li.hasNext()){ Object obj = li.next(); if(obj.equals("java02")) li.add("java009"); } System.out.println(al); } 运行结果: [java01, java02, java009, java03, java008]
3.2.3 ListIterato API
3.3 List常见的子类对象
/* * Collection * |--List:元素有序。元素可以重复。因为该集合体系有索引。 * |--ArrayList : 底层数据结构是数组结构。 特点:查询、修改速度很快。增加、删除速度很慢。 线程不同步。 * |--LinkedList : 底层数据结构是链表结构。 特点:增删速度很快,查询稍慢。 * |--Vector : 底层是数组数据结构。线程同步。被ArrayList替代了。 * * |--Set:元素无序。元素不可以重复。 * * */
3.4 Vector
/* * 枚举是Vector特有的取出方式。 * 枚举和迭代器很像。 * * 其实枚举和迭代器一样。 * 因为枚举的名称和方法名都过长,所以被迭代器取代。 * */ public class VectorDemo { public static void main(String[] args) { Vector v = new Vector(); v.add("java01"); v.add("java02"); v.add("java03"); Enumeration en = v.elements(); while(en.hasMoreElements()){ System.out.println(en.nextElement()); } } }
3.5 LinkedList
3.5.1 LinkedList特有方法
package com.collection; import java.util.*; /* * LinkedList特有方法: * addFirst(E e); * addLast(E e); * * getFirst(); * getLast(); * 获取元素但不删除元素。如果集合中没有元素,NoSuchElementException。 * * removeFirst(); * removeLast(); * 获取元素删除元素。如果集合中没有元素,NoSuchElementException。 * * 在JDK1.6出现了替代方法 * offerFirst(E e); * offerLast(E e); * 插入元素 * * peekFirst(); * peekLast(); * 检索但不删除元素。如果此列表为空,则返回 null 。 * * pollFirst(); * pollLast(); * 检索并删除元素。如果此列表为空,则返回 null 。 * */ public class LinkedListDemo { public static void main(String[] args) { LinkedList link = new LinkedList(); link.addFirst("java01"); link.addFirst("java02"); link.addFirst("java03"); link.addFirst("java04"); System.out.println(link); //[java04, java03, java02, java01] System.out.println(link.getFirst()); //java04 System.out.println(link.getLast()); //java01 System.out.println(link.removeFirst()); //java04 System.out.println(link); //[java03, java02, java01] while(!link.isEmpty()){ link.removeFirst(); } } }
3.5.1 LinkedList练习
import java.util.*; /* * 使用LinkedList模拟堆栈或者队列数据结构 * * 堆栈:先进后出。如同杯子。 * 队列:先进先出。如同水管。 * * */ public class LinkedListTest { public static void main(String[] args) { Queue q1 = new Queue(); q1.myAdd("java01"); q1.myAdd("java02"); q1.myAdd("java03"); q1.myAdd("java04"); while(!q1.isNull()){ System.out.println(q1.myGet()); } } } class Queue{ private LinkedList link; Queue(){ link = new LinkedList(); } public void myAdd(Object obj){ link.addFirst(obj); } public Object myGet(){ return link.removeLast(); } public boolean isNull(){ return link.isEmpty(); } }
3.5.2 LinkedList API
3.6 ArrayList
import java.util.*; /* * 去除ArrayList集合中的重复元素 * */ public class ArrayListTest { public static void main(String[] args) { ArrayList al = new ArrayList(); al.add("aaa"); al.add("bbb"); al.add("bbb"); al.add("def"); al.add("ggg"); singleElement(al); //[aaa, bbb, def, ggg] } public static void singleElement(ArrayList al){ //定义一个临时容器 ArrayList al1 = new ArrayList(); ListIterator li = al.listIterator(); while(li.hasNext()){ Object obj = li.next(); if(al1.indexOf(obj) == -1){ al1.add(obj); } } System.out.println(al1); } }
import java.util.*; /*将自定义对象存入ArrayList中,并删除重复元素*/ public class ArrayListTest2 { public static void main(String[] args) { ArrayList<Person> al = new ArrayList<Person>(); al.add(new Person("张三",20)); al.add(new Person("李四",25)); al.add(new Person("王五",21)); al.add(new Person("李四",25)); ArrayList newAl = singleElement(al); Iterator<Person> it = newAl.iterator(); while(it.hasNext()){ Person p = it.next(); System.out.println(p.getName() + "::" + p.getAge()); } } public static ArrayList singleElement(ArrayList al){ //定义一个临时容器 ArrayList al1 = new ArrayList(); ListIterator li = al.listIterator(); while(li.hasNext()){ Object obj = li.next(); if(!al1.contains(obj)){ al1.add(obj); } } return al1; } } class Person{ private String name; private int age; Person(String name,int age){ this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName(){ return name; } public int getAge(){ return age; } public boolean equals(Object obj){ if(!(obj instanceof Person)) return false; Person p = (Person)obj; return p.name.equals(this.name) && p.age == this.age; } } 运行结果: 张三::20 李四::25 王五::21
contains实际上是调用对象的equals方法。
结论:
List集合判断元素是否相同,依据的是元素的equals方法。
其他:
remove、indexof底层其实用的也是元素的equals方法。
ArrayList API