相同点:都是用来存储多个数据类型的容器
不同点:存储的灵活性
① 长度: 数组一旦创建长度固定;集合可以灵活存储
② 数据类型: 数据可存放指定的一种数据类型,既可以是基本数据类型也可以是引用数据类型;集合只能存放任意的引用数据类型(如果赋值基本数据类型,底层以基本数据类型的包装类存储,自动装箱的形式完成)
① 存储特点
Collection接口: 既可以存储重复值,也可以存储不重复值;既可以有序,也可以无序
List接口: 有序不唯一
Set接口: 无序且唯一
Queue接口: 先进先出 队列式存储
② 实现类底层存储模式
ArrayList类: 底层基于动态数组存储
LinkedList类: 底层基于双链表存储
TreeSet类: 底层基于二叉树存储
HashSet: 底层基于哈希码值存储
// 可调整大小的数组的实现List接口
Class ArrayList<E>
< E> – 表示泛型
① 泛型的含义: 泛指的任意的引用数据类型
② 泛型使用的格式: <字母> – 字母一般是任意一个,必须得大写
java中规定的泛型字母 | 含义 |
---|---|
E | Element,表示集合中存储元素的类型 |
K | KEY,表示Map中键的类型 |
V | VALUE,表示Map集合中值的类型 |
R | Result,表示方法的返回值类型 |
? | 表示不确定的任意一种类型 |
T | Type,存储的类型 |
③ 使用泛型的好处:提高集合存储数据的安全性;一旦集合使用泛型,等效于数组;实际开发中,一般在集合使用的时候,必须配合泛型使用
ArrayList对象有初始值;长度是10;可以进行扩容;扩容的倍数是1.5
public class ArrayListTest {
public static void main(String[] args) {
ArrayList list=new ArrayList();
// 直接打印集合对象,显示集合中所有元素
System.err.println(list);
}
}
// 在集合的尾部追加指定的元素
public boolean add(E e)
// 将指定的元素插入到集合的指定位置上
public void add(int index ,E e)
// 例子
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<Object> list=new ArrayList<Object>();
list.add("qq");
list.add(13);
list.add(false);
list.add('@');
// 指定下标添加元素
list.add(2,5);
list.add("qq");
list.add(0,23);
System.err.println(list);
//[23, qq, 13, 5, false, @, qq]
}
}
// 清空集合中所有数据,但是保留集合结构
public void clear()
// 移除指定位置上的元素,并且返回该元素
public E remove(int index)
// 将指定元素从集合中移除(如果存在)
public boolean remove(E e)
// 例子
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<Object> list=new ArrayList<Object>();
list.add("qq");
list.add(13);
list.add(false);
list.add('@');
// 指定下标添加元素
list.add(2,5);
list.add("qq");
list.add(0,23);
System.err.println(list);
// [23, qq, 13, 5, false, @, qq]
// 删除指定元素时若元素类型是整数或字符型,需将值传递为元素对象进行删除
// 因为可能会将传递的值认为是下标,造成数组下标越界
// 值转对象:类型强转 (包装类)值
System.err.println("移除元素5"+list.remove((Integer)5));
// 移除元素5true
System.err.println(list);
// [23, qq, 13, false, @, qq] 删除成功返回 true
System.out.println("移除位置3上的元素:"+list.remove(3));
// 移除位置3上的元素:false(返回元素本身)
System.out.println(list);
list.clear();
System.out.println("清空后的list"+list);
}
}
// 使用指定的元素修改指定位置上的原有元素,将原有的元素返回
public E set(int index,E e )
// 例子
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<Object> list=new ArrayList<Object>();
list.add("qq");
list.add(13);
list.add(false);
list.add('@');
// 指定下标添加元素
list.add(2,5);
list.add("qq");
list.add(0,23);
System.err.println(list);
// [23, qq, 13, 5, false, @, qq]
System.out.println("用!替换1位置上的元素"+list.set(1,"!"));
// 返回指定位置上的元素 用!替换1位置上的元素qq
System.out.println("替换后"+list);
// 替换后[23, !, 13, 5, false, @, qq]
}
}
// 获取集合指定位置上的元素
public E get(int index)
// 获取指定元素在集合中第一次出现的位置,如果不存在返回-1
public int indexOf(E e)
// 获取指定元素在集合中最后一次出现的位置,如果不存在返回-1
public int lastIndexOf(E e)
// 获取集合元素的真实个数
public int size()
// 获取集合中指定范围内的所有元素,不包含结束位置
public List<E> subList(int beginIndex,int endIndex)
// 例子
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<Object> list=new ArrayList<Object>();
list.add("qq");
list.add(13);
list.add(false);
list.add('@');
// 指定下标添加元素
list.add(2,5);
list.add("qq");
list.add(0,23);
System.err.println(list);
// [23, qq, 13, 5, false, @, qq]
System.out.println("集合长度"+list.size());
// 集合长度7
System.out.println("2位置上的元素"+list.get(2));
// 2位置上的元素13
System.out.println("qq第一次出现的位置"+list.indexOf("qq"));
// qq第一次出现的位置1
System.out.println("qq最后一次出现的位置"+list.lastIndexOf("qq"));
// qq最后一次出现的位置6
System.out.println("[1,3)范围内的元素"+list.subList(1,3));
// [1,3)范围内的元素[qq, 13]
}
}
// 判断指定的元素是否是集合中的元素
public boolean contains(E e)
// 例子
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<Object> list=new ArrayList<Object>();
list.add("qq");
list.add(13);
list.add(false);
list.add('@');
// 指定下标添加元素
list.add(2,5);
list.add("qq");
list.add(0,23);
System.err.println(list);
// [23, qq, 13, 5, false, @, qq]
System.out.println("@在集合中吗"+list.contains('@'));
// @在集合中吗true
}
}
// 获取指定单列集合中元素的最大值
public static E max(Collection<E> c)
// 获取指定单列集合中元素的最小值
public static E min(Collection<E> c)
// 给指定的List集合进行默认的升序排序
public static void sort(List<E> list)
// 将指定的多个散数据(引用数据类型),同时存放到List 集合中,Arrays类提供
public static List<T> asList( T ..... t)
// 例子
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<Integer>();
list.add(13);
list.add(7);
list.add(45);
list.add(2);
list.add(2,5);
list.add(0,23);
System.err.println(list);
// [23, 13, 7, 5, 45, 2]
Collections.sort(list);
System.out.println("排序后"+list);
// 排序后[2, 5, 7, 13, 23, 45]
System.out.println("最大"+Collections.max(list));
System.out.println("最小"+Collections.min(list));
// 最大45 最小2
}
}
// 将任意的多个引用数据类型同时存储在List集合中
public class ArrayListTest {
public static void main(String[] args) {
List<Object> list = Arrays.asList("qwer", 'e', 456, Math.PI, true);
System.err.println(list);
// [qwer, e, 456, 3.141592653589793, true]
// list是接口对象,因此不能直接调用接口中的抽象方法完成操作
// 需将list集合的数据放到ArrayList中,通过ArrayList对象调用方法完成操作
ArrayList<Object> als=new ArrayList<Object>();
for (Object o: list) {
als.add(o);
}
als.add("asdwd");
System.out.println(als);
// [qwer, e, 456, 3.141592653589793, true, asdwd]
}
}
// 双向链表
Class LinkedList<E>
// 创建集合
public LinkedList()
// 将指定的元素插入到链表的头部
public void addFirst(E e)
//将指定的元素查入到链表的尾部
public void addLast(E e)
// 例子
public class ArrayListTest {
public static void main(String[] args) {
LinkedList<Integer> ll=new LinkedList<>();
ll.add(12);
ll.add(122);
ll.add(142);
ll.add(2,22);
System.err.println(ll);
// [12, 122, 22, 142]
ll.addFirst(-11);
ll.addLast(-22);
System.err.println(ll);
// [-11, 12, 122, 22, 142, -22]
}
}
// 移除链表中头部位置上的元素
public E removeFirst()
// 移除链表中尾部位置上的元素
public E removeLast()
// 例子
public class ArrayListTest {
public static void main(String[] args) {
LinkedList<Integer> ll=new LinkedList<>();
ll.add(12);
ll.add(122);
ll.add(142);
ll.add(2,22);
System.err.println(ll);
// [12, 122, 22, 142]
ll.removeFirst();
System.err.println(ll);
// [122, 22, 142]
}
}
① 队列式存储: 先进先出,类似于吸管
存: LinkedList类 – addFirst()
取: LinkedList类 – removeLast()
② 堆栈式存储 : 先进后出
存:LinkedList类中 – addFirst()
取:LinkedList类中 – removeFirst()
public class PriStack<T> {
// 定义私有化变量LinkedList
private LinkedList<T> ll;
// 定义当前类有参构造器,参数是用户传递的LinkedList对象
public PriStack(LinkedList<T> ll){
this.ll=ll;
}
// 存数据
public void save(T t){
ll.addFirst(t);
}
// 取数据
public T gain(){
return ll.removeFirst();
}
// 显示集合元素
public void show(){
System.err.println(ll);
}
// 取元素个数
public int size(){
return ll.size();
}
}
public class PriStackTest {
public static void main(String[] args) {
PriStack<String> ps=new PriStack<String>(new LinkedList<String>());
ps.save("this a");
ps.save("this b");
ps.save("this c");
ps.show();
// [this c, this b, this a]
while (ps.size()>0){
System.out.println(ps.gain());
}
//this c
//this b
//this a
}
}
① 泛型可以使用的位置 : 类 和 类成员 (一般成员方法)
② 泛型使用的前提: 定义的类或类成员完成对数据的存取操作时
// 此类实现Set接口
public class HashSet<E>
// 创建对象
public HashSet()
public class play {
public static void main(String[] args) {
HashSet<Object> hs=new HashSet<>();
hs.add("132");
hs.add(213);
hs.add('*');
hs.add("dw");
hs.add(5.5);
System.out.println(hs);
// [132, dw, 213, 5.5, *]
}
}
// 向集合存放十个数,以升序排序的方式显示,同时显示最大最小值
public class play {
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
// 注意优先级问题
list.add((int)(Math.random()*100));
}
System.err.println("排序前"+list);
Collections.sort(list);
System.err.println("排序后"+list);
System.err.println(Collections.max(list));
System.err.println(Collections.min(list));
}
}
// 方式二
public class play {
public static void main(String[] args) {
HashSet<Integer> hashSet=new HashSet<Integer>();
while (hashSet.size()<10){
hashSet.add((int) (Math.random()*100));
}
System.err.println(hashSet);
System.err.println(Collections.max(hashSet));
System.err.println(Collections.min(hashSet));
}
}
① 存
for(int i=0;i<数组名.length;i++){
数组名[i]=值;
}
② 取
//当需要操作元素下标的时候 -- 使用普通for循环
for(int 1=0; i<数组名.length;i++){
变量=数组名[i];
}
//当需要直接操作数组元素的时候 -- 使用增强for (forEach)
for(数据类型 变量名 : 数组名){
操作变量;
}
① 存数据 – 普通for循环
for(int i = 0; i<数值;i++){
集合对象名.add(E e);
}
//推荐使用while原因集合长度不限,因此很少指定长度
while(true){
集合对象名.add(E e);
if(判断条件){
break;
}
}
② 取数据
//方式一:根据元素下标获取元素 普通for
for(int i= 0 ;i<集合对象名.size();i++){
对象=集合对象名.get(i);
}
//方式二:直接操作元素 增强for
for(类 对象 : 集合名){
操作对象;
}
//方式三: 迭代器,java封装好的一个接口Iterator迭代接口
Iterator<集合泛型的类型> it = 集合对象名.iterator();//获取迭代器对象
while(it.hasNext()){//判断下一个位置是还有元素
对象=it.next();//获取集合中的元素
}
① 存数据
//由于Set集合没有位置,因此只能使用while循环添加数据
while(true){
集合对象名.add(E e);
if(判断条件){
break;
}
}
② 取数据
for(类 对象: 集合名){
操作对象;
}
通过集合对象获取迭代器对象,通过迭代器对象调用hasNext(),此时游标指针创建,默认停放的位置是-1,表示没有获取到元素;通过while循环启动游标指针,在指定的单列集合中移动
在迭代器中对该方法限定移动范围[0,集合对象名.size())
// 迭代器只操作单列集合
public class play {
public static void main(String[] args) {
HashSet<Integer> hashSet=new HashSet<Integer>();
while (hashSet.size()<10){
hashSet.add((int) (Math.random()*100));
}
System.err.println(hashSet);
// 通过单列集合对象调用iterator()方法获取迭代器对象,有迭代器对象才能调用迭代器方法
Iterator<Integer> it=hashSet.iterator();
// 通过迭代器对象调用方法,判断集合中下一个位置上是否还有元素,有则继续
while (it.hasNext()){
// 元素存在,通过迭代器对象获取元素赋值给i,显示
Integer i=it.next();
// 显示大于60的元素
if(i>60){
System.err.println(i);
}
}
}
}
① 将键值看做一个对象进行存储(以键值对(KEY - VALUE)形式存储数据)
② KEY不能重复,VALUE可以重复的
③ 每一对的KEY-VALUE都是 一一对应的映射关系
① KEY不可以重复 – KEY所在的集合一定是Set
② VALUE可以重复 – VALUE所在的集合是Collection(可重复,且无序)
public class play {
public static void main(String[] args) {
HashMap<String,Object> map=new HashMap<String,Object>();
System.err.println(map); //{}
}
}
// 将指定的键值对存放在指定的集合中
public V put(Object key,Object value)
// 例子
public class play {
public static void main(String[] args) {
HashMap<String,Object> map=new HashMap<String,Object>();
System.err.println(map.put("NMG","内蒙古"));
System.err.println(map.put("LN","辽宁"));
System.err.println(map.put("HLJ","黑龙江"));
System.err.println(map.put("JL","吉林"));
// null
System.err.println(map.put("HLJ","黑龙江省"));
// 黑龙江
System.err.println(map);
// {JL=吉林, HLJ=黑龙江, NMG=内蒙古, LN=辽宁}
}
}
当KEY不存在时,返回值结果为null,表示当前的键值对关系还没有确立,可以存储到Map集合中
当KEY存在的时,返回值结果为上一次的VALUE的值,表示当前键值对已存在,会使用本次的VALUE将原有VALUE替换掉
// 清空集合中所有的键值对,但保留集合结构
public void clear()
// 根据指定的KEY移除键值对,并返回VALUE(如果KEY存在,不存在返回null)
public V remove(Object key)
// 当且仅当key与value为键值对时,才执行移除操作(返回true)
public boolean remove(Object key,Object value)
// 例子
public class play {
public static void main(String[] args) {
HashMap<String,Object> map=new HashMap<String,Object>();
System.err.println(map.put("NMG","内蒙古"));
System.err.println(map.put("LN","辽宁"));
System.err.println(map.put("HLJ","黑龙江"));
System.err.println(map.put("JL","吉林"));
System.err.println(map.remove("NMG"));
// 内蒙古
System.err.println(map.remove("nmg"));
// null
System.err.println(map.remove("LN","辽宁"));
// true
System.err.println(map);
// {JL=吉林, HLJ=黑龙江}
map.clear();
System.err.println(map);
// {}
}
}
// 使用参数value替换指定key原有value(如果key存在)
public V replace(Object key,Object value)
// 当且仅当key与old为键值对时,才使用newValue替换old值
public boolean replace(Object key,Object old,Object newValue)
// 例子
public class play {
public static void main(String[] args) {
HashMap<String,Object> map=new HashMap<String,Object>();
System.err.println(map.put("NMG","内蒙古"));
System.err.println(map.put("LN","辽宁"));
System.err.println(map.put("HLJ","黑龙江"));
System.err.println(map.put("JL","吉林"));
System.err.println(map.replace("JL","吉林省"));
// 吉林
System.err.println(map.replace("jl","吉林"));
// null
System.err.println(map.replace("LN","辽宁","辽宁省"));
// true
System.err.println(map);
// {LN=辽宁省, JL=吉林省, HLJ=黑龙江, NMG=内蒙古}
}
}
// 根据指定key获取value
public V get(Object key)
// 获取Map集合中所有KEY所在集合
public Set<KEY> keySet()
// 获取Map集合中所有VALUE所在集合
public Collection<VALUE> values()
// 获取集合中键值对的个数
public int size()
// 例子
public class play {
public static void main(String[] args) {
HashMap<String,Object> map=new HashMap<String,Object>();
System.err.println(map.put("NMG","内蒙古"));
System.err.println(map.put("LN","辽宁"));
System.err.println(map.put("HLJ","黑龙江"));
System.err.println(map.put("JL","吉林"));
System.err.println(map.get("LN")); // key对应的value
// 辽宁
System.err.println(map.keySet()); //所有的key集合
// [LN, JL, HLJ, NMG]
System.err.println(map.values()); //所有的value集合
// [辽宁, 吉林, 黑龙江, 内蒙古]
System.err.println(map.size()); // 集合中键值对的个数
// 4
System.err.println(map);
// {LN=辽宁, JL=吉林, HLJ=黑龙江, NMG=内蒙古}
}
}
// 判断指定的KEY是否存在于集合中
public boolean containsKey(Object key)
// 判断指定的VALUE是否存在于集合中
public boolean containsValue(Object value)
// 例子
public class play {
public static void main(String[] args) {
HashMap<String,Object> map=new HashMap<String,Object>();
System.err.println(map.put("NMG","内蒙古"));
System.err.println(map.put("LN","辽宁"));
System.err.println(map.put("HLJ","黑龙江"));
System.err.println(map.put("JL","吉林"));
System.err.println(map.containsKey("LN"));
// true
System.err.println(map.containsValue("辽宁"));
// true
System.err.println(map);
// {LN=辽宁, JL=吉林, HLJ=黑龙江, NMG=内蒙古}
}
}
定义三个市(每个市有其景点),从键盘录入指定的市,如果市存在显示其景点,并且可以对其进行修改
public class play {
public static void main(String[] args) {
// 定义三个市
HashMap<String,String[]> map=new HashMap<String,String[]>();
map.put("上海市",new String[]{"城隍庙","田子坊","东方明珠"});
map.put("澳门",new String[]{"永利皇宫","美狮美高梅","黑沙码头"});
map.put("香港",new String[]{"兰桂坊","太平山","M+"});
// 显示市对应的所有景点
Scanner sc=new Scanner(System.in);
System.out.println("请输入城市:");
String city=sc.next();
if(map.containsKey(city)){
System.out.println(city+"的景点有"+Arrays.toString(map.get(city)));
} else {
System.out.println(city+"目前没有信息");
}
// 修改澳门的景点信息
if(map.containsKey("澳门")){
String[] newCity=map.get("澳门");
for (int i = 0; i < newCity.length; i++) {
if(newCity[i].equals("永利皇宫")){
newCity[i]="葡京";
break;
}
}
System.out.println("澳门替换后的景点信息:"+Arrays.toString(map.get("澳门")));
}
// 修改上海市的景点信息
if(map.containsKey("上海市")){
String[] names={"外滩","迪士尼","五角场"};
map.replace("上海市",names);
System.out.println("上海替换后的信息"+Arrays.toString(map.get("上海市")));
}else {
System.out.println("错误操作");
}
sc.close();
}
}