集合框架1
①集合
定义:是对象的容器,定义了对多个对象进行操作的方法.可以实现数组的功能。
与数组的区别:
- 数组长度固定,集合长度不固定。
- 数组可以存储基本类型和引用类型,集合只能存储引用类型。
位置:java.util.*;
②Collection父接口
特点:代表一组任意类型的对象,无序,无下标,不可重复.
方法 | 作用 |
---|---|
boolean add(Object obj) | 添加一个对象 |
boolean addAll(Collection c) | 将一个集合中的所有对象添加到此集合中 |
void clear() | 清空此集合中的所有对象 |
boolean contains(Object obj) | 检查集合中是否有obj对象 |
boolean equals(Object obj) | 比较此集合是否与指定对象相等 |
boolean isEmpty() | 判断此集合是否为空 |
boolean remove(Object obj) | 在此集合中移除obj对象 |
int size() | 返回此集合中的元素个数 |
Object[ ] toArray() | 将此集合转换成数组 |
-添加,删除,遍历,判断
import java.util.*;
public class Main{
public static void main(String[] args) {
//创建集合
Collection collection = new ArrayList();
//1.添加元素add()
collection.add("苹果");
collection.add("西瓜");
collection.add("香蕉");
collection.add("榴莲");
System.out.println("元素个数:" + collection.size()); //元素个数:4
System.out.println(collection.toString()); //[苹果, 西瓜, 香蕉, 榴莲]
//2.删除元素remove()
//collection.remove("榴莲");
//System.out.println(collection.toString()); //[苹果, 西瓜, 香蕉]
//清空元素
//collection.clear();
//System.out.println(collection.toString()); //[]
//3.遍历元素
//3.1使用增强for循环
for(Object obj : collection){
System.out.println(obj);
}
//3.2使用迭代器(专门用来遍历集合的一种工具)
// hasNext()是否有下一个元素
// next() 返回获取的集合中的元素
// remove() 删除当前元素
Iterator it = collection.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.print(str + " "); //苹果 西瓜 香蕉 榴莲
//--在迭代过程中无法使用Collection的删除方法,如果需要删除元素,只能使用Iterator中的remove()方法-- 否则会报并发修改异常
if(str.equals("榴莲")){
it.remove();
}
}
System.out.println(collection); //[苹果, 西瓜, 香蕉] 成功在迭代中将符合条件的元素进行了删除
//4.判断
System.out.println(collection.contains("苹果")); //true
System.out.println(collection.isEmpty()); //false
}
}
import java.util.*;
public class Main{
public static void main(String[] args) {
//新建Collection对象
Collection collection = new ArrayList();
Student s1 = new Student("iFinder",20);
Student s2 = new Student("Bob",16);
Student s3 = new Student("Jacy",22);
//1.添加数据
collection.add(s1);
collection.add(s2);
collection.add(s3);
System.out.println(collection.toString()); //[Student [ name = iFinder,age = 20 ], Student [ name = Bob,age = 16 ], Student [ name = Jacy,age = 22 ]]
//2.删除元素
collection.remove(s1);
collection.remove(new Student("iFinder",20)); //虽然新建对象属性与s1相同,但是二者不是同一个对象实例
System.out.println(collection); //[Student [ name = Bob,age = 16 ], Student [ name = Jacy,age = 22 ]]
//清空元素 .clear()
//注意:这里的删除与清空指的是将元素从集合中删除.元素的本体依旧在内存中存储.
//3.遍历
//3.1增强for循环
for(Object obj : collection){
Student stu = (Student)obj;
System.out.println(stu);
}
//3.2迭代器
Iterator it = collection.iterator();
while(it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.toString());
if(stu.getName().equals("Jacy")) it.remove();
}
System.out.println(collection);
//4.判断
System.out.println(collection.contains(s1)); //false
System.out.println(collection.isEmpty()); //false
}
}
//定义一个学生类
class Student{
String name;
int age;
//无参构造
public Student(){
}
//有参构造
public Student(String name ,int age){
super();
this.name = name;
this.age = age;
}
//javaBean
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 "Student [ name = " + name + ",age = " + age + " ]";
}
}
③List集合
特点:有序的,有下标的,元素可重复的
- 常用方法
方法 | 作用 |
---|---|
void add(int index , Object obj) | 在index位置插入对象obj |
boolean addAll(int index , Collection c) | 将集合c中的元素添加到原集合的index位置 |
Object get(int index) | 返回集合中指定位置的元素 |
List subList(int fromIndex , int toIndex) | 返回fromIndex到toIndex之间的元素 |
int indexOf(E e) | 返回传入参数对应的角标,若列表中不存在,返回-1 |
import java.util.*;
public class Main{
public static void main(String[] args) {
//List接口,是有序的,有下标的,可重复的
//创建集合对象
List list = new ArrayList();
//1.添加元素
list.add("iPhone");
list.add("XiaoMi");
list.add(0,"HuaWei"); //在指定位置添加元素
System.out.println(list.toString()); //[HuaWei, iPhone, XiaoMi]
//2.删除元素
//list.remove(0);
//list.("iPhone");
//list.clear();
//3.遍历
//3.1使用for遍历
for(int i = 0;i < list.size();i++){
System.out.println(list.get(i));
}
for(Object obj : list){
System.out.println(obj);
}
//3.2使用迭代器
Iterator it = list.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.println(obj);
}
System.out.println("---------------------------------");
//3.3使用列表迭代器ListIerator
/*
可以向前进行遍历
boolean hasPrevious(); E previous();
可以在遍历的过程中添加元素
add(E e);
可以替换元素
void set(E e)用传入的元素替换next()或previous()返回的元素
可以返回角标int nextIndex(); int previousIndex()
*/
ListIterator listIt = list.listIterator();
while(listIt.hasNext()){ //从前往后遍历
System.out.println(listIt.nextIndex() + ":" + listIt.next());
}
while(listIt.hasPrevious()){ //从后往前遍历
System.out.println(listIt.previousIndex() + ":" + listIt.previous());
}
//4.判断
System.out.println(list.contains("iPhone")); //true
System.out.println(list.isEmpty()); //false
//5.获取位置
System.out.println(list.indexOf("iPhone")); //1
}
}
import java.util.*;
//list存储操作数据时需要注意
public class Main{
public static void main(String[] args) {
//创建集合
List list = new ArrayList();
//1.添加数字数据(集合只能保存引用类型,所以在传入值的时候进行了自动装箱操作)
list.add(20);
list.add(30);
list.add(40);
list.add(50);
list.add(60);
System.out.println("元素个数:" + list.size()); //元素个数:5
System.out.println(list.toString()); //[20, 30, 40, 50, 60]
//2.删除操作
//list.remove(20);直接传值会通过角标删除 报错:java.lang.IndexOutOfBoundsException: Index 20 out of bounds for length 5
// 方法1 list.remove((Object)20);
list.remove(new Integer(20));
System.out.println(list.toString());
//3.subList()的使用
List lst = list.subList(1,3); //从1开始到3的元素--含头不含尾
System.out.println(lst); //[40,50]
}
}
- List实现类
ArrayList:
- 数组结构实现,查询快,增删慢
- JDK1.2之后提供,运行效率快,但是线程不安全
Vector:
- 数组结构实现,查询快,增删慢
- JDK1.0之后提供,运行效率慢,但是线程安全
LinkedList:
- 链表结构实现,查询慢,增删快
- ArrayList的使用
特点:有序的,有下标的,元素可重复的
查找,遍历速度快,增删速度慢
存储结构:数组
import java.util.*;
public class Main{
public static void main(String[] args) {
//创建集合
ArrayList alist = new ArrayList();
//1.添加元素
Student s1 = new Student("iFinder",20);
Student s2 = new Student("JacyKa",24);
Student s3 = new Student("Nancy",18);
alist.add(s1);
alist.add(s2);
alist.add(s3);
System.out.println("元素个数:" + alist.size());
System.out.println(alist.toString()); //[Student [ name = iFinder,age = 20 ], Student [ name = JacyKa,age = 24 ], Student [ name = Nancy,age = 18 ]]
//2.删除元素
//alist.remove(s2);
//System.out.println(alist.toString()); //[Student [ name = iFinder,age = 20 ], Student [ name = Nancy,age = 18 ]]
//实现传入匿名对象的删除操作
//alist.remove(new Student("Nancy",18)); //equals(this == obj)是通过比较地址才导致不能实现该操作,若要实现,需重写Student中的equals方法
//System.out.println(alist.toString()); //[Student [ name = iFinder,age = 20 ]] 重写equals()方法后删除成功
//alist.clear(); 清空所有元素
//3.遍历元素
//3.1使用for/增强for进行遍历--参看list
//3.2使用迭代器进行遍历
Iterator it = alist.iterator(); //普通迭代器
while(it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.toString());
}
ListIterator lit = alist.listIterator(); //列表迭代器
while(lit.hasNext()){ //正序遍历效果相同
Student stu = (Student)lit.next();
System.out.println(stu.toString());
}
while(lit.hasPrevious()){
Student stu = (Student)lit.previous();
System.out.println(stu.toString());
}
//4.判断
System.out.println(alist.contains(s1)); //true
System.out.println(alist.contains(new Student("iFinder",20))); //ture 因为重写了equals方法,所以这里的返回值为true
System.out.println(alist.isEmpty()); //false
//5.查找get()
}
}
//定义一个学生类
class Student{
String name;
int age;
//无参构造
public Student(){ }
//有参构造
public Student(String name ,int age){...}
//javaBean
public String getName(){...}
public void setName(String name){...}
public int getAge(){...}
public void setAge(int age){...}
@Override
public String toString(){...}
//重写equals方法
public boolean equals(Object obj){
//1.判断是否为同一个对象
if(this == obj){
return true;
}
//2.判断传入的对象是否是null
if(obj == null){
return false;
}
//3.判断是否为Student类
if(obj instanceof Student){
Student s = (Student)obj;
//4.比较属性
if(this.name.equals(s.getName()) && this.age == s.getAge()){
return true;
}
}
//5.都不满足
return false;
}
}
- ArrayList源码分析
- 默认容量大小:DEFAULT_CAPACITY = 10 (private static final int) 加元素后
没有向集合中添加元素时默认容量为0 DEFUALTCAPACITY_EMPTY_ELEMENTDATA- 存放元素的数组: elementData (Object[ ])
- 实际的元素个数: size (private int)
- add()方法
public boolean add(E e){
ensureCapacityInternal(size + 1); //Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity){
if(elementData == DEFUALTCAPACITY_EMPTY_ELEMENTDATA){
minCapacity = Math.max(DEFUALT_CAPACITY,minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity){
modCount++; //增加次数
//overflow-conscious code
if(minCapacity - elementData.length > 0){
gorw(minCapacity); //核心扩容代码
}
}
private void grow(int minCapacity){ //扩容核心代码 扩容大小为原长度的1.5倍
//overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //右移以为相当于除二
if(newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if(newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity); //大量数据(Integer.MAX_VALUE - 8)加入时的扩容
//minCapacity is usually close to size , so this is a win:
elementData = Arrays.copyOf(elementData,newCapacity); //将旧数组拷贝到新数组当中
}
- Vector的使用
数组结构实现,查询遍历快,增删慢
JDK1.0版本,线程安全,运行效率慢
方法 | 作用 |
---|---|
Enumeration<E> elements() | 返回此向量的组件的枚举(与Iterator相似) |
E firstElement() | 返回集合中的第一个元素 |
E lastElement() | 返回集合中的最后一个元素 |
import java.util.*;
public class Main{
public static void main(String[] args) {
//创建集合
Vector ve = new Vector();
//1.添加元素
ve.add("草莓");
ve.add("香蕉");
ve.add("芒果");
ve.add("西瓜");
System.out.println(ve.toString());
//2.删除元素 remove(int index); remove(E e);
//清空元素 clear()
//3.遍历
//3.1 for,增强for,迭代器--参看ArrayList
//3.2使用枚举器进行遍历
Enumeration en = ve.elements();
while(en.hasMoreElements()){ //与迭代器的使用方法相似
String str = (String)en.nextElement();
System.out.println(str);
}
//4.判断 contains(E e), isEmpty()
//5.firstElement() lastElement() 获取第一个,最后一个元素
//get(int index)通过角标获取元素
}
}
- LinkedList的使用
链表的结构实现,增删快,查询慢
import java.util.*;
public class Main{
public static void main(String[] args) {
//LinkedList存储结构,双向链表
//创建集合
LinkedList link = new LinkedList();
Student s1 = new Student("iFinder",13);
Student s2 = new Student("JacyNa",10);
Student s3 = new Student("Nancy",18);
Student s4 = new Student("BobBy",16);
//1.添加元素
link.add(s1);
link.add(s2);
link.add(s3);
link.add(s4);
System.out.println(link.toString());
//2.删除元素
//link.remove(1);
//link.remove(s1);
//link.clear();
//3.遍历集合
//3.1 for ,增强for → 结合get()方法
//3.2迭代器
Iterator it = link.iterator();
while(it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu);
}
//3.3列表迭代器
ListIterator lit = link.listIterator();
while(lit.hasNext()){
Student stu = (Student)lit.next();
System.out.println(stu);
}
//4.判断 contains() isEmpty()
//5.获取
System.out.println(link.indexOf(s1)); //0
}
}
//定义一个学生类
class Student{
String name;
int age;
//无参构造
public Student(){
}
//有参构造
public Student(String name ,int age){
super();
this.name = name;
this.age = age;
}
//javaBean
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 "Student [ name = " + name + ",age = " + age + " ]";
}
}
- LinkedList源码分析
int size() 集合的大小
Node first 链表的头结点
Node last 链表的尾节点
void linkLast(E e){
final Node<E> l = last;
final Node<E> newNode = new Node<>(l,e,null);
last = newNode;
if(l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
private static class Node<E>{
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev,E element,Node<E> next){
this.item = element;
this.next = next;
this.prev = prev;
}
}
- ArrayList与LinkedList的区别
ArrayList
LinkedList
- ListIterator迭代器方法补充
方法 | 说明 |
---|---|
void add(E e) | 将指定元素插入列表 |
boolean hasNext() | 如果迭代器在遍历时有更多元素,则返回true |
boolean hasPrevious() | 如果迭代器反向遍历时有更多的元素,返回true |
E next() | 返回列表中的下一个元素并后移光标位置 |
int nextIndex() | 返回next()元素的角标 |
E previous() | 返回前一个元素并前移光标位置 |
int previousIndex() | 返回previous()元素的角标 |
void remove() | 从列表中删除next()或previous()返回的最后一个元素 |
void set() | 用指定的元素替换next()或previous()返回的最后一个元素 |