java集合总结

一下内容均为原创,如有不对,还请指正。
说集合之前先来说说数组,其实数组也集合的一种(集合也称容器)
数组的变量可以是基本数据类型也可以是引用类型,数组可以看成是一个对象,其中的每个元素相当于该对象的成员变量
一. 数组的三种初始化形式
1.静态初始化
该初始化可直接向数组中放元素。形式:

int[] a = {2,4,6};

2.默认初始化
该初始化的形式为new一个对象(前文也提及数组本身可看作一个对象),默认初始化之后jdk会给数组一个系统默认的初始化值(0,null)形式:

int[]b = new int[3]; //默认赋值

默认初始化后,我们可以对它进行动态初始化赋值或者循环初始化赋值

3.动态初始化赋值
不说多了直接上代码,肯定能看懂

int[] c = new int[2];
int[0] = 1;
int[1] = 2;

需要注意的是数组的首位索引为0;

二.数组的遍历
数组的遍历,我了解两种遍的方式
1.for循环遍历
数组是一个有序的集合(即什么顺序放,什么取)可以使用for循环遍历(链表结构的集合不能用这种方式 下文会提及)

int[]a = new int [4];
for(int i = 0;i<=a.length;i++);//这里的a.length为4
{
	a[i] = 100*i;
}//for循环往数组里面放元素
for(int i = 0;i<a.length;i++)
{
	System.out.println(a[i]);
}//for循环遍历数组

2.foreach循环遍历
foreach是一种功能强大的遍历集合的方式(几乎所有集合都可以用这种方式遍历)
foreach的底层是Iterator迭代器(后文会提及)

for(int m : a){
System.out.println(m);
}

值得一提的是forea循环只用于collection以及数组的遍历。

三.数组的拷贝
数组的拷贝是一个很重要的功能,实现数组的扩容和删除本质上都是数组的拷贝。
下面是代码

System.arrayCopy(src,srcPos,dest,destPos,length)
/*从src拷贝到dest,srcPos代表开始拷贝被拷贝数组的索引位置,
destPos代表拷贝到的数组的索引位置,length代表拷贝数组的长度。*/

1.数组的删除
数组的删除本质上是数组的拷贝

String s1[] = {"aa"."bb","cc","dd","ee"};
System.arrayCopy(s1,3,s1,2,s1.length-3);
s1[s1.length-1] = null;
for(int i = 0;i<s1.length;i++)
{
	System.out.println(s1[i]);
}//删除cc元素

2.数组的扩容
本质上是,先定义一个更大的数组然后将原数组的内容原封不动的拷贝到新数组中

String[] s1 = {"aa","bb","cc"};
String[] s2 = new String[s1.length+10];
System.arrayCopy(s1,0,s2,0,s1.length);

基于此原理我们也可以进行数组的插入,但是众所周知数组的插入效率比较低。

四.数组的工具类使用

System.out.println(Array.toString(a));//打印数组
Arrays.sort(a);/*对数组进行排序,默认升序,此方法可实现Compable接口并重写ComoareTo方法
也可实现Comparator的接口并重写其Compare方法*/
Arrays。binarySeach(a.-30);//查找-30在数组a的哪个位置

五.泛型
1.泛型是一种未知的数据结构,当我们不知道使用什么数据类型的时候,可以使用泛型。当然泛型也可以看成是一个变量,用来接收数据类型。创建集合对象的时候就会确定泛型的数据类型。
如:ArrayList<String> list = new ArrayLilst <>();
创建好集合对象之后,规定其泛型。
2.使用泛型有以下好处:
(1).使用泛型避免了类型转换的麻烦,存储的是什么类取出的就是什么类
(2).把运行期异常(代码运行之后会抛出异常)提早到了编译期异常(写代码时就会报错)
值得注意的是若创建集合对象时不适用泛型,默认是object类型,可以存储任意数据类型,但不安全,容易引发异常。
3.定义含有泛型的方法
(1)定义在方法的修饰符和返回值类型之间
如:修饰符<泛型>返回值类型 方法名 (参数列表(使用的泛型)){方法体};
(2).含有泛型的方法在调用方法时确定泛型的数据类型,传递什么类型的参数,泛型就是什么类型。
4.泛型的通配符
(1)<?>:代表任意数据类型
(2)不能创建对象使用,只能作为方法的参数使用。
(3)定义时不能用,作为参数传递时可以使用。
(4)泛型的上限限定:?extends E:使用的泛型只能是E类型的子类本身
泛型的下限限定:?super E:使用的泛型只能是E类型的父类本身

六.常见的数据结构
1.栈:先进后出
2.队列:先进先出
3.数组:查询快,增删慢
(1)数组的地址连续课通过首地址找到数组,通用索引可快速查找某一个元素。
(2)数组的长度是固定的,我们想增删,必须创建一个新数组将原数组拷贝过来
4.链表:查询慢,增删快
(1)地址不连续,每次查询一个元素是,都必须重头查询
(2)增删一个元素,对链表的整体结构没有影响,所以增删快
(3)链表的每一个元素也称为一个节点,一个节点包含一个数据域(存储数组),两个指针域(存储地址,包括自己的地址和下一个节点的地址)
(4)链表包括单项链表(不能保证元素顺序)和双向链表(可以保证元素顺序)
5.树
(1)二叉树 :分支不能超过两个的树
(2)排序树 :在二叉树的基础上,元素有大小顺序,左子树小,右子树大。查询速度很快类似于二分法
(3)平衡树 :左子树和右子树相等(与此相对应的还有不平衡树)
(4)红黑树:特点 趋近于平衡树,查询速度非常快,查询叶子节点的最大次数与最小此数不能超过两倍。 约束:/节点可以是红色或者黑色 /根节点是黑色/叶子节点(空节点)是黑色/每个红色的节点的子节点都是黑色的/任何一个节点到其每个叶子的节点的所有路径上黑色节点数相同。
在这里插入图片描述 图源知乎

七.集合
1.集合只能存储对象不能存储基本数据类型(数组两者都能保存)
2.集合的长度是可以变化的(数组长度不能变化)
3.集合框架的学习方法:
(1)学习顶层:学习顶层的接口/抽象类中共性的方法。所有子类都可以使用。
(2)使用底层:底层不是接口就是抽象类 无法创建对象使用,需要创建底层的子类创建对象使用

八.Collection接口
1.它定义了所有单列集合中共性的方法,而且所有单列集合都可以使用共性的方法:没有带索引的方法
2.Collection常用功能
(1)add(E e)添加一个元素,返回值为boolean, 一般为true
(2)clear()清空集合所有元素,但不是删除(只是把集合中的地址删掉)
(3)remove(E e)移除集合中的元素 返回值为Boolen
(4)contains(E e)判断集合中是否包含此元素 返回值为Boolean
(5)isEmpty()判断集合是否为空
(6)size()判断集合有多少元素 返回值为int
(7)toArray()把集合存储到数组中

3.List接口
为Collection的子接口
(1)是一个有序的集合,即存储和取出的顺序一致
(2)允许重复元素存储
(3)用户可以根据元素的整数索引(在数组的位置)访问元素,并搜索列表的元素

(4)list特有的带索引的方法有四个(特有)
①.add(index,e) ②.remove(index)
③.set(index,A)④.get(index)

4.ArrayList类
(1)ArrayList是List接口的实现类,线程不同步,它的底层为数组结构,所以增删慢,查询快(根据地址值找到此数组,再通过索引快速查找某一元素)ArrayList长度可以在运行时发生改变,当我们不知道具体有多少元素需要存储时用此集合就比较方便。
ArrayList在初始化时为默认长度0(jdk1.6时初始化长度为10)当我们添加元素后,长度会变为10,下一次再添加元素时若长度不够,则变为上一次长度的1.5倍。

ArrayList <> list = new ArrayList<>();//指定泛型
List<> l = new ArrayList; //多态

(2)ArrayList中常用的方法

public boolean add(E,e);
public E get(int index);
public E remove(int index);
public int size ();

(3)遍历ArrayList

for(int i  = 0;i<list.size;i++)
{
	System.out.println(list.get(i));
}  //跟遍历数组类似,实际上还有多种遍历此集合的方式

5.LinkedList
(1)LinkedList也是List的一个实现类,底层是一个链表结构(双向链表),故增删快,查询慢,且线程不同步。

(2)LinkedList找到头跟尾的特别方便所以有大量操作头尾的方法

addFirst(E e);
addLast (E e);
getFirst (E e);
getLast (E e);
removeFirst (E e);
removeLast (E e);
pop (); //相当于removeFirst (E e);
push (E e);//相当于addFirst(E e);

当使用LinkedList集合特有的方法时,不能使用多态(有任何想使用子类方法的操作时,都不能使用多态)。

6.Vertor
底层为数组结构,跟ArrayList极其相似,但是Vertor为单线程效率低。遍历用向量枚举的形式elements(E e)

7.set接口
set接口为Collection的子接口
(1)不包含重复元素
(2)没有索引,与Collection的方法一样,没有带索引的方法。且不能使用foe循环遍历。
(3)set接口有两个实现类HashSet,TreeMap
*HashSet由哈希表支持,查询速度非常快,不保证Set的迭代顺序,且为多线程。使用迭代器foreach遍历
LinkedHashSet是HashSet的子类底层是哈希表(数组+链表+红黑树)+链表:多了一条链表记录元素的顺序,保证元素有序,但是还是不允许重复。

九。Map接口
1.Map集合 Map<K,V>//两个泛型一一对应
将键映射到值,K不允许重复,每个K最多只能映射一个V,但是V可以重复。
2.Map为双列集合,Collection为单列集合
3.Map集合中的元素,key和value可以相同也可以不同
4.Map的特有方法
(1)put(k,v)
(2)remove(object key)
(3)get(object key)
(4)containsKey(object key)

4.HashMap
(1)HashMap为Map接口的一个实现类 它不保证映射的顺序,特别是该顺序恒久不变。无序集合,多线程
(2)底层是哈希表,增删速度特别快(因为有next指针指向下一个节点,通过改变指针的指向可以方便的进行数据的增删)查询速度慢(因为没有索引的缘故 每次只能从头查询) jdk1.8之前是数组+单向链表 jdk1.8之后是数组+单向链表+红黑树
*LinkedHashMap是HashMap的子类,它的特点有
①.LinkedHashMap底层是哈希表+链表结构
②因为多了一条链表来记录顺序故,LinkedHashMap为一个有序集合存储取出顺序一致。

5.Map集合的遍历
1.键找值遍历
(1)用keySet()方法把集合中的key值取出来放到一个set集合中
(2)使用增强for来遍历这个set集合同时通过get()方法来获取值,通过这种键找值得方法来遍历Map集合

public class MapDemo01 {
public static void main(String[] args) {
//创建Map集合对象
HashMap<String, String> map = new HashMap<String,String>();
//添加元素到集合
map.put("胡歌", "霍建华");
map.put("郭德纲", "于谦");
map.put("薛之谦", "大张伟")
Set<String> keys = map.keySet();
// 遍历键集 得到 每一个键
for (String key : keys) {
//key 就是键
//获取对应值
String value = map.get(key);
System.out.println(key+"的CP是:"+value);
		}
	}
}

2.Entry键值对对象
(1)Map.Entry<k,v>在Map接口有一个内部接口Entry
作用:当Map集合创建,那么就会在Map集合中创建一个Entry对象用来记录键与值(键值对对象,键值的映射关系)
(2)使用entrySet()把Map集合内部的多个Entry对象取出来,存储到一个Set集合中。
(3)遍历此Set集合获取其中的Entry对象
(4)使用Entry对象中的方法getKey(),getValue().获取其中的键值

public class MapDemo02 {
public static void main(String[] args) {
// 创建Map集合对象
HashMap<String, String> map = new HashMap<String,String>();
// 添加元素到集合
map.put("胡歌", "霍建华");
map.put("郭德纲", "于谦");
map.put("薛之谦", "大张伟");
// 获取 所有的 entry对象 entrySet
Set<Entry<String,String>> entrySet = map.entrySet();
// 遍历得到每一个entry对象
for (Entry<String, String> entry : entrySet) {
// 解析
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"的CP是:"+value);
		}
	}
}

6.HashMap保存自定义类型键值
(1)HashMap存储自定义类型的键值,Map集合必须保证key是唯一的,而作为key的元素,必须重写hashCode和equals方法
(2)此自定义类型中若自定义的是key则必须重写,若自定义的是value则不必重写

7.Hashtable<k,v>
(1)Hashtable不允许存储null,底层也是哈希表
(2)它是最早的双列集合,单线程,效率慢,线程安全
(3)Hashtable和Vertor在jdk1.2的时候被更先进的集合HashMap和ArrayList取代。但Hashtable的子类Properties依旧活跃,因为它是唯一个和IO流结合的集合

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值