Java集合
Collection接口和常用方法
-
Collection接口实现类的特点
public interface Collection< E > extends lterable < E >
1、 Collection实现子类可以存放多个元素,每个元素可以是Object
2、有些Collection的实现类,可以存放多个元素,每个元素可以是Object
3、有些Collection的实现类,有些是有序的(List)有些不是有序(Set)
4、Collection接口没有直接的实现子类,是通过它的子接口Set 和 List来实现的
-
Collcetion接口常用方法
1、add:添加单个元素
2、remove:删除指定元素
3、contains:查找元素是否存在
4、size:获取元素个数
5、isEmpty:判断是否为空
6、clear:清空
7、addAll:添加多个元素
8、containsAll:查找多个元素是否都存在
9、removeAll:删除多个元素
-
Collection接口遍历元素方式1-使用Iterator(迭代器)
1、Iterator对象称为迭代器,主要用于 遍历Collection集合的元素。
2、所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iteraror接口的对象,既可以返回一个迭代器。
3、Iterator 的结构图。
4、Iterator仅用于遍历集合,Iterator本身并不存放对象。
-
迭代器的执行原理
Iterover itreover = coll.iterator();
hasNext();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
注意:在调用iterator.next()方法之前必须要调用iterator.hasNext()进行检测,若不调用,且吓一跳记录无效,直接调用it.next()会抛出NoSuchElementException异常。
package com.shuai.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionIterator {
@SuppressWarnings({"all"})
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三国演义", "罗贯中", 16.8));
col.add(new Book("水浒传", "施耐庵", 18.8));
col.add(new Book("红楼梦", "曹雪芹", 19.8));
Iterator iterator = col.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println("obj"+obj);
}
iterator = col.iterator();
System.out.println("===============第二次遍历===============");
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println("obj"+obj);
}
}
}
class Book {
private String name;
private String author;
private double price;
public Book(String name, String author, double price) {
this.name = name;
this.author = author;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
}
-
Collection接口遍历对象方式2-for循环增强。
增强for循环,可以代替iterator迭代器,特点:增强for循环就是简化版的iterator,本质一样,只能用于遍历集合或数组。
基本语法:
for(元素类型 元素名:集合名或数组名){
访问元素
}
package com.shuai.collection;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionFor {
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三国演义", "罗贯中", 16.8));
col.add(new Book("水浒传", "施耐庵", 18.8));
col.add(new Book("红楼梦", "曹雪芹", 19.8));
col.add(new Book("西游记", "吴承恩", 15.8));
for (Object book:col){
System.out.println("book="+book);
}
}
}
练习:编写程序CollectionExercise.java
-
1、创建3个Dog{name,age}对象,放入到ArrayList中,赋给List引用
-
2、用迭代器和增强for循环两种方式来遍历
-
3、重写Dog的toString方法,输出name和age
package com.shuai.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class CollectionExercise {
@SuppressWarnings({"all "})
public static void main(String[] args) {
List list = new ArrayList();
list.add(new Dog("大白", 3));
list.add(new Dog("小黑", 2));
list.add(new Dog("尼克", 6));
for (Object dog : list) {
System.out.println("dog=" + dog);
}
System.out.println("=======使用迭代器循环遍历======");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object Dog = iterator.next();
System.out.println("Dog=" + Dog);
}
}
}
class Dog {
private String name;
private int age;
public Dog(String name, int age) {
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 "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
List接口和常用方法
-
List接口是Collection接口的子接口 List.java
1、List集合中元素有序(添加顺序个和取出顺序一致)、且可重复。
2、List集合中的每一元素都有其对应的顺序索引,即支持索引。
3、List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
4、JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。
-
List接口的常用方法 ListMethod.java,
List集合离添加了一些根据索引来操作集合元素的方法
package com.shuai.collection;
import java.util.ArrayList;
import java.util.List;
public class ListMethod {
@SuppressWarnings({"all"})
public static void main(String[] args) {
List list = new ArrayList();
list.add("刘备");
list.add("张飞");
list.add(1,"关羽");
System.out.println("list=" + list);
List list1 = new ArrayList();
list1.add("马超");
list1.add("赵云");
list.addAll(1,list1);
System.out.println("list=" + list);
System.out.println("list=" + list);
System.out.println(list.get(1));
System.out.println(list.indexOf("张飞"));
list.add("赵云");
System.out.println("list=" + list);
System.out.println(list.lastIndexOf("赵云"));
list.remove(0);
System.out.println("list=" + list);
System.out.println("list="+list);
list.set(1,"黄忠");
System.out.println("list=" + list);
List returnList = list.subList(1, 4);
System.out.println("returnList=" + returnList);
}
}
练习:
package com.shuai.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListExercise {
@SuppressWarnings("all")
public static void main(String[] args) {
List list = new ArrayList();
for (int i = 0; i < 11; i++) {
list.add("hello" + i);
}
System.out.println("list=" + list);
list.add(1,"Nike");
System.out.println("list=" + list);
System.out.println("第五个元素=" + list.get(4));
list.remove(5);
System.out.println("list="+ list);
list.set(6,"修改");
System.out.println("list="+ list);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println(obj);
}
}
}
ArrayList底层结构和远吗分析
-
ArrayList的注意事项
1、permits all elements , including null , ArrayList 可以加入null,并且多个
2、ArrayList 是由数组来实现数据存储的
3、ArrayList 基本等同于Vector , 除了ArrayList是线程不安全(执行效率高),在多线程的情况下,不建议使用ArrayList
package com.shuai.collection;
import java.util.ArrayList;
public class ArrayListDetail {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add(null);
arrayList.add("make");
arrayList.add(null);
System.out.println(arrayList);
}
}
### ArrayList底层结构和源码分析
-
ArrayList的底层操作机制源码分析(重点,难点)
1、ArrayList中维护了一个Object类型的数组elementData.[debug 看源码]transient Object[] elementData;
2、当创建对象时,如果使用的是无参构造器,则初始elementData容量为0(jdk7是10)
3、当添加元素时:先判断是否需要扩容,如果需要扩容,则调用grow方法,否则直接添加元素到合适的位置
4、如果使用的是无参构造器,如果第一次添加,需要扩容的话,则扩容elementData为10,如果需要再次扩容的话,则扩容elementData为1.5倍
5、如果使用的是指定容器capacity的构造器,则初始elementData容量为capacity
6、如果使用的是指定容器capacity的构造器,如果需要扩容,则直接扩容elementData为1.5倍
Vector底层结构和源码剖析
-
Vcector的基本介绍
1、 Vector类的定义说明
public class Vectoir<E>
extends AbstractList<E>
implements List<E>,RandomAccess,Cloneable,Serializable
2、Vector底层也是一个对象数组,protected Object[] elementData;
3、Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
public synchronized E get(int index){
if(index >= elementCount){
throw new ArrayIndexOutOfBoundsExecption(index);
return elementData(index);
}
}
4、在开发中,需要线程同步安全时,考虑使用Vector
Vector底层结构和ArrayList的比较
-
Vector和ArrayList的比较
| 底层结构 | 版本 | 线程安全(同步)效率 | 扩容倍数 |
---|
ArrayList | 可变数组 | jdk1.2 | 不安全,效率高 | 如果有参构造1.5倍;如果是无参第一次10从第二次开始按1.5倍扩容 |
Vector | 可变数组 | jdk1.0 | 安全,效率不高 | 如果是无参,默认10,满后,按2倍扩容;如果指定大小,则每次直接按2倍扩 |
LinkedList底层结构
-
LinkedList的全面说明
1、LinkedList实现了双向链表和两端队列的特点
2、可以添加任意元素(元素可以重复),包括null
3、线程不安全,没有实现同步
-
LinkedList底层操作机制
1、LinkedList底层维护了一个双向链表
2、LinkedList中维护了两个属性first和last分别指向首节点和尾节点
3、每个节点(Node对象)里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表。
4、说以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高
ArrayList 和 LinkedList比较
| 底层结构 | 增删的效率 | 改查的效率 |
---|
ArrayList | 可变数组 | 较低,数组扩容 | 较高 |
LinkedList | 双向链表 | 较高,通过链表追加 | 较低 |
-
如何选择ArrayList和LinkedList:
1、改查造作较多,选择ArrayList
2、增删操作较多,选择LinkedList
3、一般来说,在程序中。80%-90%都是查询,因此大部分情况下会选择ArrayList
4、在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList。
Set接口和常用方法
-
Set接口基本介绍
-
1、无序(添加和取出的顺序不一样),没有索引
-
2、不允许重复元素,所以最多包含一个null
package com.shuai.set_;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetMethod {
public static void main(String[] args) {
Set set = new HashSet();
set.add("make");
set.add("faker");
set.add("ale");
set.add("jack");
set.add("faker");
set.add(null);
set.add(null);
System.out.println("set=" + set );
for (int i = 0; i < 10; i++) {
System.out.println("set=" + set );
}
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println("obj=" + obj );
}
for (Object o :set) {
System.out.println("o=" + o);
}
}
}
Set接口实现类-HashSet
package com.shuai.set_;
import java.util.HashSet;
public class HashSet01 {
public static void main(String[] args) {
HashSet set = new HashSet();
System.out.println(set.add("make"));
System.out.println(set.add("key"));
System.out.println(set.add("faker"));
System.out.println(set.add("jack"));
System.out.println(set.add("key"));
System.out.println(set.add("sky"));
set.remove("key");
System.out.println("set=" + set);
set = new HashSet();
set.add("Rose");
set.add("Rose");
set.add(new Dog("noke"));
set.add(new Dog("noke"));
System.out.println("set=" + set);
set.add(new String("mata"));
set.add(new String("mata"));
System.out.println("set=" + set);
}
}
class Dog {
private String name;
public Dog(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
}
Set接口实现类-HashSet
-
HashSet底层机制说明
-
HashMap底层是(数组+链表+红黑树)
package com.shuai.set_;
public class HashSetStructure {
public static void main(String[] args) {
Node[] table = new Node[16];
Node jack = new Node("jack",null);
table[2] = jack;
Node faker = new Node("faker",null);
jack.next = faker;
Node meike = new Node("meike",null);
faker.next = meike;
Node sky = new Node("sky",null);
table[3] = sky;
System.out.println("table=" + table);
}
}
class Node {
Object item;
Node next;
public Node(Object item, Node next) {
this.item = item;
this.next = next;
}
}