Java学习 --集合和数组

11 篇文章 0 订阅

集合和数组:
都是对多个数据进行存储操作的结构,加成java容器。

数组存储的特点:

  • 一旦初始化以后,长度就确定了,元素类型也就确定了。对于指定一个数组,我们只能操作指定类型的数据。
  • 数组存储数据是有序且可重复的。对于无序、不可重复的需求不能满足。
  • 初始化后长度不可修改。

Collections是操作collection、map的工具类。
集合存储:
JDK提供的集合API位于java.util包内。

Collection 是创建单列集合的接口

包含两个接口:list接口和set接口

list接口

●鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组
●List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。
●List容器中的元索都对应一个整数型的序号记载其在容器中的位置,可以根据.
序号存取容器中的元素。
●JDK API中List接口的实现类常用的有: ArrayList、 LinkedList 和Vector。

  • ArrayList: 作为ist接口的主要实现类;线程不安全的,效率高;底层使用object[] eLementData存储
  • 建议开发中使用带参构造器,初始化数组。
  • LinkedList: 对于频繁的插入、删除操作,使用此类效率比Arraylist高;底层使用双向链表存储
  • Vector: 作为List接口的古老实现类;线程安全的,效率低;底层使用object[] elementData存储

ArrayList源码分析结果:
在创建集合时实际上是在底层创建了数组。
在jdk8中,
Arraylist list = new ArrayList();
底层object[] elementData 初始化为{}.并没有初始化数组,
list. add(123);//第一一次调用add()时,底层才创建了长度10的数组,并将数据123添加到eLementdata中,
后续的添加和扩容操作与jdk 7无异。
如果此次的添加导致底层elementData数组容量不够,则扩容。
默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。
jdk8与jdk7相比延迟了数组创建时间,节省了内存。

创建集合对象:

collection coll = new ArrayList();//有序集合
collection coll1 = Array.aslist(123,456)

接口中常用的方法:
1.添加元素
可以是字符串,数字,类的实例化对象,布尔值等,

coll.add(元素)//默认在末尾加

coll.add(位置,元素)//在指定位置插入元素
coll.addAll(位置,某一集合)//在指定位置开始将集合中所有元素添加到当前集合中
//默认在集合末尾添加

注意:向Collection接口中添加类的实例化对象时,要求所在类要重写equals()
2.判断当前集合中是否包含某个元素

boolean contains = coll.contains(123)//返回一个布尔值

在判断是否含有某个对象时:

对于系统中现有的类,会重写比较器,调用的是equal()。即比的是内容。在判断时会调用obj对象所在类的equals().
对于我们自己写的类默认调用的是object类中的,比较的地址。可以在自己重写equals()方法。

3.判断某个集合的元素是否都在当前集合中

coll.containAll(coll1);//返回的是布尔型

4.从当前集合中移除某个元素
返回的是布尔型,表示是否移除成功
先进行比较。

coll.remove(1234)
coll.remove(索引//删除某索引位置的元素。返回的该位置上的元素

5.从当前集合中移除另一个集合中所有的元素

coll.remove(coll1)

6.求当前集合与coll1集合的交集,并把交集保留给当前集合

coll.retainAll(coll1)

7.判断两个集合是否相等

coll.equals(coll1)//返回布尔型

8.判断两个集合是否相等
arraylist对象是有序的,两个集合相等,顺序也相等。
arraylist创建的集合对象必须是数据和形参以及数据的顺序也相等时,才返回true。

coll.equals(coll1)

9.hashCode():
返回当前对象的哈希值

10.将集合转换为数组。

coll.toArray();//返回的是object[]类型的数组

11.将数组转换为集合

arrays.alist(数组)//返回的是集合

12.集合中元素的个数 长度
对于int类型的数组,注意用Integer创建数组。

coll.size()//返回个数

13.集合元素的遍历 遍历
使用迭代器Iterator接口

Iterator iterator = coll.iterator();//创建一个迭代器对象。

方式一:

iterator.next()//返回第一个集合元素

有多少个元素就遍历next()几次。

方式二
利用for循环遍历

for(i=0;i<coll.size();i++{
System.out.println(iterator.next());

方式三:
括号内用于判断是否还有未遍历的元素

while(iterator.**hasNext()**){
System.out.println(iterator.next());

每次创建的新的迭代器对象的指针都在开头的上面。每次重新遍历都要重新创建迭代器。

14.Iterator迭代器remove()
可以删除集合中某个元素

while(iterator.hasNext()){
Object obj = iterator.next()
if("Tom".equals(obj){
iterator.remove();
}

15.利用增强for循环遍历集合
内部调用的还是迭代器
for(集合元素的类型 局部变量:集合对象)
增强for循环相当于把每个元素取出来赋给了一个新的变量,因此无法通过增强for循环对数组进行修改。

for(Object obj :coll){
...
}

16.获取指定位置的元素

coll.get(0)

17.获取元素在集合中首次出现的位置
没有该元素会返回-1

index = coll.indexOf(456)

18.获取元素在集合中最后出现的位置
不存在返回-1

index = coll.lastindexOf(456)

19.修改某位置上的元素

coll.set(1,"C");//将索引位置1上的元素改为“C”

20.获取集合中部分元素并放在新的集合中
原集合不变

List sub = list.subList(2,4
Set接口

存储无序、不可重复的数据。就是高中讲的集合定义

无序性:不等于随机性。以hashset为例,存储的数据在底层数组中并非按照数组索引顺序添加。而是根据数据的哈希值决定的。
不可重复:保证添加的元素,保证添加的元素按照equals()判断时,不能返回true。即相同的元素只能添加一个。

Set接口的实现类常用的有:
HashSet: 作为Set接口的主要实现类;线程不安全的;可以存储null 值,底层用数组+链表存储,
存储过程:
每个元素对应一个哈希值,哈希值通过某种计算方法计算出元素在数组中的位置(即为相应索引位置),
判断此位置上是否已经有元素,如果没有元素,则直接添加成功,如果有元素,比较哈希值:
当两个元素哈希值不同,会利用链表的方式,将数组中的元素指针指向该元素。
当两个元素的哈希值相同,会调用equals()方法判断两个元素是否相等,不相等则按照链表的方式存储该元素。相等则不存储该元素。
另外,
添加的类中一定要重写hashCode()(object类中的hashCode()方法是随机算一个数,即使两个类定义的内容相同,哈希值也不同。)和equals().这两个方法尽量要保持一致性,自动生成就行。。
LinkedHashSet: 作为HashSet的子类; 利用迭代器遍历其内部数据时,可以按照添加的顺序遍历.
在添加数据(与上面类似)的同时,每个数据还维护了两个 引用,记录此数据的前一个数据和后一个数据,因此能够按照顺序遍历。也需重写hashcode()和equals()
优点:对于频繁的遍历操作,其效率高于HashSet。
TreeSet:可以按照添加对象的指定属性, 进行排序。
添加的数据,要求是
相同类的对象。

利用迭代器遍历时会按照从小到大排序
对于自己创建的类,需在进行比较,类中实现比较接口
比较时不在利用equals()而是用compare to(需要在自定义的类中进行实现comparable接口重写)进行比较。底层是树形结构

1.创建对象

Set set = new HashSet();

2.添加元素
可以是字符串,数字,类的实例化对象,布尔值等,

coll.add(元素)

其他方法与上面类似

Map接口–创建多列数据接口

存放双列数据:存储key-value对的数据。
类似于高中讲的函数:y=f(x)。

对Map结构的理解:
Map中的key:无序的、不可重复的,使用Set 存储所有的key
Map中的value:无序的、可重复的,使用Collection 存储所有的value
一个键值对: key-value 构成了一个Entry对象。
Map中的entry:无序的、不可重复的,使用Set 存储所有的entry

Map 接口的几个实现类

HashMap: 作为Map的主要实现类;线程不安全的,效率高;存储null 的key和value
LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素。
对于频繁的遍历操作,此类执行效率高FHashMap。
**TreeMap:**保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key 的自然排序或定制排序
底层使用红黑树,向treeMap中添加key-value时,要求key必须是同一个类创建的对象。因为要按照key进行排序。自定义的类中需重写比较方法。
**Hashtable:**作为古老的实现类;线程安全的,效率低;不能存储null的key和value
**Properties:**常用来处理配置文件。key和value 都是String类型

请添加图片描述

HashMap map = new HashMap():
在实例化以后,底层创建了长度是16的- -维数组Entry[] table。
…可能已经执行过多次put… .
map. put(key1, value1):jdk7 过程分析
首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry 数组中的存放位置。
如果此位置上的数据为空,此时的key1 -value1添加成功。---- 情况1
如果此位置上的数据不为空,(意味着此位置上存在一一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据
的哈希值:
如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1 添加成功。---- 情况2.
如果key1的哈希值和已经存在的某一个数据(key2-value2) 的哈希值相同,继续比较:调用key1 所在类的equals(key2)
如果equals()返回false:此时key1-value1添加成功。---- 倩况3
如果equals().返回true:使用value1替换value2。

在不断的添加过程中,会涉及到扩容问题,默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。

jdk8相较于jdk7在底层实现方面的不同:

  1. new HashMap():底层没有创建-一个长度为16的数组
  2. jdk 8底层的数组是: Node[],而非Entry[J]
  3. 首次调用put()方法时,底层创建长度为16的数组
  4. jdk7底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树。
    当数组的某一个索引位置上的元素以链表形式存在的数据个数> 8且当前数组的长度> 64时,
    此时此索引位置上的所有数据改为使用红黑树存储。

Map接口中常用的方法
以hashmap为例
首先需要实例化map对象

Map map = new HashMap();

1.添加

map.put("AA",123);
map.put(45,123);
map.put("AA",345);//会覆盖上面的123
Syatem.out.println(map)
Map map1 = new HashMap();
map1.put("CC",123);
map1.put("tt",567);
map.putAll(map1);

2.移除

Object value = map.remove("CC");//移除key为CC的数据,返回value值

3.清空

map.clear();//清空集合,集合还在

4.集合大小
返回map中key-value对的个数

map.size();

5.判断是否为空

boolean isEmpty()

6.获得value

map.get(23)//获取key为23的value

如果key不存在,则返回null
7.是否包含指定key

map.containsKey("23")//返回布尔值

8.是否包含指定value

map.containsValue("23")//返回布尔值

9.判断是否相等
equals()

10.遍历

迭代器只能对collection使用
获取key集

Set set = map.keySet();//获取所有的key
//此时可以用迭代器遍历set
Iterator iterator = set.iterator();
while (iterator.hasNext())
{
	System.out.println(iterator.next());
}
set集可以用for循环迭代吗。

获取values集

Collection values = map.values();
for (Object obj :values){
...
}

分开获取得到的key和value一一对应,先后顺序一致

遍历所有的key-value
获取所有entry构成的set集合

Set entrySet = map.entrySet();
Iterator iterator1 = entrySet.iterator();
while (iterator1.hasNext())
{
	Object obj = iterator1.next();
	Map.entry entry = (Map.Entry) obj;
	System.out.println(entry.getKey()+"=====>"+entry.getValue());
}

也可以利用以下方法。
请添加图片描述
collections工具类常用方法
是操作collection和map的工具类

请添加图片描述

请添加图片描述
Collections类中也提供了多个synchronizedXxx()方法,
该方法可使将指定集合包装成线程同步的集合,从而可以解决
多线程并发访问集合时的线程安全问题。

//返回的List1即为线程安全的List
List list1 = Collections.synchronizedList(list);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值