扁平化设计个人网站,咋样做网站视频,网上挣钱正规渠道,网站平台设计团队第2节 集合#xff08;上#xff09;
因为已经有数据结构的基础#xff0c;前面有关数据结构的知识就不单独整理了#xff0c;直接上Java的集合类的知识。
一、类集#xff08;集合类#xff09;
1.1 集合概述
集合#xff1a; 集合是java中提供的一种容器#xff…第2节 集合上
因为已经有数据结构的基础前面有关数据结构的知识就不单独整理了直接上Java的集合类的知识。
一、类集集合类
1.1 集合概述
集合 集合是java中提供的一种容器可以用来存储多个数据。
集合和数组的区别 数组的长度固定集合的长度可变 数组中存储的是同一个类型的元素可以存储基本数据类型值集合存储的都是对象而且对象的类型可以不一致在开发中一般当对象多的时候使用集合来进行存储。
对象数组有哪些问题普通的对象数组的最大问题在于数组中的元素个数是固定的不能动态的扩充大小所以最早的时候可以通过链表实现一个动态对象数组但是这样毕竟太复杂了所以在Java中为了方便用户操作各个数据结构引入了类集的概念有时候就可以把类集称为java对数据结构的实现 。
1.2 集合框架
JavaSE提供了满足各种需求的API在使用这些API前先了解其继承与接口操作架构才能了解何时采用哪个类以及类之间如何彼此合作从而达到灵活运用。
集合按照其存储结构可以分为两大类分别是单列集合java.util.Collection和双列集合java.util.Map。
类集中最大的几个操作接口Collection、Map、Iterator这三个接口为以后要使用的最重点的接口。所有的类集操作的接口或类都在java.util包中。
Java类集的结构图 二、Collection接口
2.1 Collection介绍
Collection接口是在整个Java类集中保存单值 的最大操作父接口Map是保存双值/键值对的最大操作父接口里面每次操作的时候都只能保存一个对象的数据此接口定义在java.util包中。
有两个重要的子接口分别是java.util.List和java.util.Set。其中List的特点是元素有序、元素可重复Set的特点是元素无序而且不可重复。List接口的主要实现类有 java.util.ArrayList和 java.util.LinkedList Set接口的主要实现类有 java.util.HashSet和java.util.TreeSet 。
此接口定义如下
public interface CollectionE extends IterableE注意这里使用了泛型所以后面在使用具体实现类的时候都需要传入具体类型。
常用方法 其中像add、iterator、size等方法很常用此接口的全部子类或子接口就将全部继承以上的方法。
但是在开发中不会直接使用 Collection接口而比较常使用它的子接口 List和 Set。
三、List接口
3.1 List概述
习惯性地会将实现了List接口的对象称为List集合在List集合中允许出现重复元素所有的元素是以一种线性方式存储的可以通过索引来访问集合中的指定元素。
List接口的特点 它是一个元素存取有序 的集合例如存元素的顺序是11、22、33那么集合中元素的存储就是按照11、22、33的顺序完成的。与Set相对 它是一个带有索引 的集合通过索引可以精确地操作集合中的元素与数组的索引是一个道理。 集合中可以有重复 的元素通过元素的equals方法来比较是否为重复的元素。
3.2 常用方法 除了继承了Collection接口的方法外还有如下常用的扩充方法了解了List接口之后需要找到此接口的实现类常用的实现类由如下三个
ArrayList95% 、 Vector4% 、 LinkedList1%
3.3 ArrayList类
ArrayList是 List接口的子类 此类的定义如下
public class ArrayListE extends AbstractListE
implements ListE, RandomAccess, Cloneable, SerializableArrayList集合数据存储的结构是数组结构元素增删慢查找快由于日常开发中使用的最多的功能为查询数据、遍历数据所以ArrayList是最常用的集合。
3.3.1 构造方法 这里涉及到一个容易被问的地方初始容量是一开始就给了容量为10的空间吗
这要从源码来解释
ArrayListString all new ArrayListString();从创建ArrayList开始进入空参数构造方法
public ArrayList() {this.elementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}来查看DEFAULTCAPACITY_EMPTY_ELEMENTDATA的值
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA {};
是一个空的对象数组所以使用无参构造方法新创建的ArrayList对象初始容量是0。
但是一旦add一个数据进入会发生什么进入add看一下 不论是哪种方式的add当元素存满了的时候总要调用grow方法下面来看grow方法
private Object[] grow(int minCapacity) {return elementData Arrays.copyOf(elementData, newCapacity(minCapacity));
}private Object[] grow() {return grow(size 1);
}无参grow方法会调用有参grow并且传入当前容量1作为扩容的最小容量有参grow内部是调用了Arrays.copyOf函数将扩容后的数组给了elementData再看newCapacity(minCapacity) 新扩容的容量为原来的1.5倍如果比给定的最小容量小或相等判断elementDataDEFAULTCAPACITY_EMPTY_ELEMENTDATA而DEFAULTCAPACITY_EMPTY_ELEMENTDATA就是空数组所以一个新创建的ArrayList必然会进入到这里返回了DEFAULT_CAPACITY, minCapacity两个中的较大值而新创建的minCapacity为1这时来看一下DEFAULT_CAPACITY 这才是初始容量为10的地方。
综上使用无参构造方法新创建的ArrayList对象起始的elementData为空数组只有在加入一个元素的时候才会初始化为10.
3.3.2 具体使用
使用格式
ArrayListInteger data new ArrayList();例子
package org.listdemo.arraylistdemo;
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo01 {public static void main(String[] args) {ListString all new ArrayListString(); // 实例化List对象 并指定泛型类型all.add(hello ); // 增加内容 此方法从Collection接口继承而来all.add(0, LAMP );// 增加内容 此方法是List接口单独定义的all.add(world); // 增加内容 此方法从Collection接口继承而来System.out.println(all); // 打印all对象调用toString()方法}
}结果如下
[LAMP , hello , world]
package org.listdemo.arraylistdemo;
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo02 {public static void main(String[] args) {ListString all new ArrayListString(); // 实例化List对象 并指定泛型类型all.add(hello ); // 增加内容 此方法从Collection接口继承而来all.add(0, LAMP );// 增加内容 此方法是List接口单独定义的all.add(world); // 增加内容 此方法从Collection接口继承而来all.remove(1); // 根据索引删除内容 此方法是List接口单独定义的all.remove(world);// 删除指定的对象System.out.print(集合中的内容是 );for (int x 0; x all.size(); x) { // size()方法从Collection接口继承而来System.out.print(all.get(x) 、 ); // 此方法是List接口单独定义的}}
}结果如下
集合中的内容是 LAMP 、
3.4 Vector类
3.4.1 概述与使用
与 ArrayList 一样 Vector 本身也属于 List 接口的子类 此类的定义如下
public class VectorE extends AbstractListE
implements ListE, RandomAccess, Cloneable, Serializable它的使用及操作与使用ArrayList本身基本没有什么区别
package org.listdemo.vectordemo;
import java.util.List;
import java.util.Vector;
public class VectorDemo01 {public static void main(String[] args) {ListString all new VectorString(); // 实例化List对象 并指定泛型类型all.add(hello ); // 增加内容 此方法从Collection接口继承而来all.add(0, LAMP );// 增加内容 此方法是List接口单独定义的all.add(world); // 增加内容 此方法从Collection接口继承而来all.remove(1); // 根据索引删除内容 此方法是List接口单独定义的all.remove(world);// 删除指定的对象System.out.print(集合中的内容是 );for (int x 0; x all.size(); x) { // size()方法从Collection接口继承而来System.out.print(all.get(x) 、 ); // 此方法是List接口单独定义的}}
}结果为
集合中的内容是 LAMP 、
Vector 属于 Java 元老级的操作类 是最早的提供了动态对象数组的操作类 在 JDK 1.0 的时候就已经推出了此类的使用只是后来在 JDK 1.2 之后引入了 Java 类集合框架。但是为了照顾很多已经习惯于使用 Vector 的用户所以在JDK 1.2 之后将 Vector 类进行了升级了 让其多实现了一个 List 接口 这样才将这个类继续保留了下来。
3.4.2 Vector与ArrayList类的区别重点 3.5 LinkedList类
3.5.1 概述
LinkedList集合数据存储的结构是链表结构方便元素添加、删除的集合。
LinkedList是一个双向链表。
3.5.2 使用
除了继承的List中的方法外还有一些关于队列或栈操作的方法以及涉及到首尾操作 例子
import java.util.LinkedList;
import java.util.Queue;
public class TestDemo {public static void main(String[] args) {QueueString queue new LinkedListString();queue.add(A);queue.add(B);queue.add(C);int lenqueue.size();//把queue的大小先取出来 否则每循环一次 移除一个元素 就少一个元素 那么queue.size()在变小 就不能循环queue.size()次了。for (int x 0; x len; x) {System.out.println(queue.poll());}System.out.println(queue);}
}结果如下
A
B
C
[]
四、Iterator迭代器接口
4.1 Iterator概述
在程序开发中经常需要遍历集合中的所有元素针对这种需求JDK专门提供了一个接口java.util.Iterator。也是Java集合中的一员但是它与Collection、Map接口有所不同Collection接口与Map接口主要用于存储元素而Iterator主要用于迭代访问即遍历Collection中的元素因此Iterator对象也被称为迭代器。 此接口定义如下public interface IteratorE要想使用此接口 则必须使用 Collection 接口 在 Collection接口中规定了一个 iterator()方法 可以用于为 Iterator 接口进行实例化操作其实要到ArrayList类这一级别因为是接口的实现类中才对Iterator接口进行了实现。
4.2 方法
此接口定义了以下三个方法 通过Collection接口为其进行实例化之后一定要记住Iterator中的操作指针是在第一条元素之上 当调用next()方法的时候 获取当前指针指向的值并向下移动 使用 hasNext()可以检查序列中是否还有元素。 看个例子
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorDemo01 {public static void main(String[] args) {CollectionString all new ArrayListString();all.add(A);all.add(B);all.add(C);all.add(D);all.add(E);IteratorString iter all.iterator();while (iter.hasNext()) {// 判断是否有下一个元素String str iter.next(); // 取出当前元素System.out.print(str 、 );}}
}结果如下
A、 B、 C、 D、 E、
Iterator接口本身可以完成输出的功能 但是此接口只能进行由前向后的单向输出。 如果要想进行双向输出 则必须使用其子接口 —— ListIterator。
4.3 ListIterator理解
ListIterator是可以进行双向输出的迭代接口是 Iterator的子接口 此接口中定义了以下的操作方法 看一下它的输出
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorDemo01 {public static void main(String[] args) {ListString all new ArrayListString();all.add(A);all.add(B);all.add(C);all.add(D);all.add(E);ListIteratorString iter all.listIterator();System.out.print(从前向后输出 );while (iter.hasNext()) {System.out.print(iter.next() 、 );} System.out.print(\n从后向前输出 );while (iter.hasPrevious()) {System.out.print(iter.previous() 、 );}}
}结果如下
从前向后输出 A、 B、 C、 D、 E、
从后向前输出 E、 D、 C、 B、 A、
但是 此处有一点需要注意的是 如果要想进行由后向前的输出 则首先必须先进行由前向后的输出。
而且它的add方法也是在指向的位置插入不是在末尾插入总之此接口一般使用较少理解为主。
五、增强for循环
forEach增强for循环最早出现在C#中用于迭代数组 或 集合只能是Collection下的集合
语法 for(数据类型 变量名:集合或数组的名称) {}
作用 代替传统for循环的复杂写法进行了简化。
看一段代码即可注意只能用于数组或Collection下的集合
package com.kaikeba.coreclasslibrary.set;
import java.util.ArrayList;
import java.util.Collection;public class foreach {public static void main(String[] args) {int[] arr {6,5,4,2,1};//传统for循环遍历/*for(int i0; iarr.length; i) {System.out.println(arr[i]);}*///forEach循环遍历for(int a:arr) {System.out.println(a);}System.out.println(------------------------);ArrayListString data new ArrayList();data.add(锄禾日当午);data.add(汗滴禾下土);data.add(谁知盘中餐);data.add(粒粒皆辛苦);for(String s:data) {System.out.println(s);}}
}结果如下
6
5
4
2
1
------------------------
锄禾日当午
汗滴禾下土
谁知盘中餐
粒粒皆辛苦