ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

集合(总)

2019-09-04 19:43:16  阅读:188  来源: 互联网

标签:迭代 对象 元素 泛型 coll 集合


集合

为什么学习java集合框架

数组的存储数据的弊端:

​ a:存储相同数据类型的有序集合、存储的数据是相同类型的
​ b:数组存储数据时 需要指定当前数组的长度而且长度不可变 (定长)

需求:
  • 使用数组存储学生信息 效率变低
  • 使用数组存储每天的新闻信息
  • 就是由于在大多数的应用场景中,数据都是动态的,导致数组存储要么浪费空间,要么浪费效率

为什么java提供集合对象存储数据信息

  • 这么多集合对象用来在不同的应用场景使用。
  • 本质上而言 其实不同的集合对象底层存储实现方案不同 不同的存储结构 适用不同的需求

在这里插入图片描述

三个知识点

泛型

什么是泛型?

广泛的类型,也是一种数据类型,而这种数据类型可以是任意类型,编写过程当中不能确定该类型,创建对象时可以指定泛型的具体类型

注意:

泛型是编译期行为,只能在编译器有效如果能够跨过编译期,那么泛型就没有任何意义

泛型类

​ 在类后加<> 括号中编写任意长度任意字符 不能是数值
​ 一般情况下我们通过大写的26个字母去声明当前泛型

​ 通常:用 T 代表type 用 E 代表element

使用:

​ 泛型类<具体类型> 变量名 = new 泛型类<具体类型>();

​ jdk1.7之后支持泛型的类型推断,就是后面那个具体类型可省略

泛型接口

​ 实现类实现泛型接口时不指定泛型类型 此时创建实现类对象是可以指定泛型类型
​ class UserServiceImpl implements UserService
​ 实现类实现泛型接口时指定泛型类型 那么将确定泛型类型
​ class UserServiceImpl implements UserService

泛型方法

​ 方法中使用泛型 该方法就是一个泛型方法
​ 静态方法无法使用泛型类中声明的泛型类型 因为泛型类型的确定是创建对象时确定的
​ 而静态方法是先于对象存在的 ,如果要使用,在当前静态方法上声明泛型类型
​ public static <泛型类型> vaid 方法名()



迭代器

迭代器:

  • Iterable 是java.lang包下的接口 实现改接口都能够作为foreach的目标
  • Iterator 是java.util包下的接口 迭代器 用来迭代当前集合对象的
  • Iterator 是一个接口 ArrayList中通过内部类完成了对于改接口的实现 获取的其实是实现类对象
  • ListIterator 是一个接口 这个接口可以支持并发修改 内部提供了add set remove方法
  • 如果对于一个List集合对象要通过使用迭代器做修改(删除、添加、修改)那么请使用ListIterator
位置:

迭代器的指针指向了集合中第一个元素前面一个位置

检查:

迭代器通过hasNext()查看下面是否存在元素

移动:

通过next()移动指针,并且返回当前指针指向的元素值。

比较器

外部比较器:

如果要使用外部比较器:

  1. 实现java.util.Compartor接口
  2. 重写compare方法
  3. 然后在compare方法中自定义排序规则(返回值为正数,不交换位置,返回值为负数,交换位置,返回0表示相等)

特点:排序规则可以随着业务扩展随时变化的。

内部比较器

如果要使用内部比较器:

  1. 实现java.lang.Comparable接口
  2. 重写compareTo方法
  3. 然后在compareTo方法中自定义排序规则(返回值为正数,不交换位置,返回值为负数,交换位置,返回0表示相等)

特点:如果需求改变,排序规则也就需要改变,但由于要准守开闭原则,就不利于后期扩展

六个接口

Collection

定义:

​ public interface Collection extends Iterable
​ 泛型

Iterable:

​ 接口 凡是继承/实现了Iterable的类 都能够作为foreach的目标
​ Iterable 是java.lang包下的接口 实现改接口都能够作为foreach的目标
​ Iterator 是java.util包下的接口 迭代器 用来迭代当前集合对象的

常见方法:

add 、clear、remove、addAll、removeAll、retainAll、size、isEmpty、contains、containsAll、iterator

迭代方法:

foreach、迭代器

public class Test01 {
    public static void main(String[] args) {
        // 学习接口中的方法 接口指向实现类对象
        Collection coll = new ArrayList();
        //添加元素
        coll.add("java");// Object obj = "java" 自动类型转换
        coll.add(1);// Integer in1 = Integer.valueOf(1); Object obj = in1;
        //添加元素
        Collection coll1 = new ArrayList();
        coll1.add("html");
        coll1.add("spring");
        System.out.println("往coll中添加coll1:"+coll.addAll(coll1));
        //删除元素:
        //coll.clear();
        System.out.println("移除不存在的元素:"+coll.remove("spring"));
        //System.out.println(coll.removeAll(coll1));
        System.out.println("coll中的元素:"+coll);
        System.out.println(coll.retainAll(coll1));
        System.out.println("coll中的元素:"+coll);
        //查看元素
        System.out.println("查看当前集合是否为null:"+coll.isEmpty());
        System.out.println("查看当前集合元素个数:"+coll.size());
        System.out.println("查看当前集合是否包含元素1:"+coll.contains("1"));
    }
}

public class Test02 {
    public static void main(String[] args) {
        //创建集合对象
        Collection coll = new ArrayList();
        //添加元素
        coll.add("String");
        coll.add("1");
        coll.add("Integer");
        coll.add("Scanner");
        //迭代元素
        System.out.println("foreach循环迭代");
        for(Object obj:coll) {
            String str = (String)obj;
            System.out.println(str);
        }
        System.out.println("iterator 迭代器");
        Iterator it = coll.iterator();//实现类对象
        while(it.hasNext()) {//下面是否存在元素 如果存在元素 返回true 如果不存在返回false
            //获取元素
            System.out.println(it.next());
        }
        System.out.println("迭代器的变种写法");
        for(Iterator it1 = coll.iterator();it1.hasNext();) {
       		System.out.println(it1.next());
        }
    }
}

List

特点:

​ 有序 可重复 可以是null值

定义:

​ public interface List extends Collection

常见方法:

增加:
add(index,obj) 指定位置增加指定元素
add(obj) 在末尾增加指定元素
addAll(Coll) 在末尾增加指定collection集合
addAll(index,coll) 在指定索引处插入指定collection集合
删除:
remove(index/obj) 删除指定索引元素/删除指定元素
clear() 删除所有元素
removeAll(Coll) 当前集合中删除指定collection集合中的所有元素(也就是删除交集)
retainAll(coll) 保留当前集合和指定集合的交集
修改:
set(index,obj) 修改指定索引的值为指定值
查看:
indexOf(obj) 查询指定元素的索引
lastIndexOf(obj) 查询指定元素最后一次出现的索引
subList(sindex,eindex) 截取从指定索引sindex到eindex的集合
isEmpty() 查询是否为空
get(index) 获取指定索引的值
size() 查询集合中元素个数
contains(obj) 查询指定元素是否存在
contaisAll(coll) 查询指定集合中的所有元素是否都在当前集合中

迭代:

普通for循环

增强foreach

迭代器(iterator[不能支持并发修改] listIterator[支持并发修改])

注:支持并发修改也就是允许在迭代器中对集合进行修改、增加、删除等操作

Set

特点:

​ 无序 唯一

定义:

​ public interface Set extends Collection

常见方法:

​ add 、clear、remove、addAll、removeAll、retainAll、size、isEmpty、contains、
​ containsAll、iterator

迭代方法:

​ foreach、迭代器

迭代器接口

Iterator 用来迭代元素

Iterable: 类实现该接口其对象即可 使用foreach

比较器接口

内部比较器

同上,三个知识点 -> 比较器

外部比较器

同上,三个知识点 -> 比较器

Map

数据:

​ k-v 键值的方式存储
​ k:唯一 无序 (set) v 无序可重复 (collection)

常见方法:

put(k,v) 在k键添加v值,如果存在键返回对应k键的值 ,添加的值会覆盖之前的值
get(k) 获取键对应的值,如果键不存在,返回null
containsKey(k) 查看键是否存在
keySet() 获取所有的key
remove(k) 删除k键对应的键值对,如果键不存在 返回null 如果存在返回值
size() 查看键值对的个数
containsValue(v) 查看值是否存在
values() 获取所有的值,返回Collection集合。
entrySet() 获取所有的键值对,返回一个set集合 该集合中的每个元素都是entry对象

迭代方法:

​ 获取键 迭代键的过程中通过get方法获取值

	for(Object key:keySet()){
			sout(k+"="+map.get(k));
	}

​ 获取Entry对象,通过getKey和getValue获取键和值

	//获取entry对象
	// 返回一个set集合 该集合中的每个元素都是entry对象
	Set<Entry<String, String>> kvs = mps.entrySet();

	// 实际是 HashSet中的Node对象 因为Node实现了Map中的Entry接口
 for(Entry<String, String> entry:kvs) {
     System.out.println(entry.getKey()+"==="+entry.getValue());
	}			

九个常用类

ArrayList:

底层:

动态数组 ,满了会扩容2倍

优缺点分析:

通过索引获取元素以及迭代元素比较快 但是添加、删除很慢

注:由于是动态数组,频繁的增加和删除,会进行频繁的扩容、缩容,会伴随着大量的拷贝操作。增加和删除时还需要对其索引后的元素进行移动,又是一波拷贝操作(移动)

常见方法:和List一致
迭代方式:和List一致

LinkedList:

底层:

双向链表()

优缺点:

添加、删除快 获取元素慢

常见方法:

和List一样,还多了一些头尾操作:
查看 getFirst、getLast、peek、 peekFirst、 peekLast、 element获取头元素
删除 poll、 pollFirst、 pollLast、 removeFirst、 removeLast
添加 offer、 offerFirst、 offerLast、 addFirst、 addLast

Vector:

底层:

数组

特点:

线程安全 速度慢1.5倍 安全

一般不使用,太慢了

HashSet:

底层:

(1.7之前jdk版本) 数组+链表 (1.8+jdk版本)数组+链表+红黑树

优缺点:

添加、删除、修改效率都很高( 结合了数组与链表的优点,先利用求得的hashCode在数组中定位查询,然后在数组元素中的链表进行增、删、改等操作,节约了大量的时间,能快速定位)

常见方法:

​ add 、clear、remove、addAll、removeAll、retainAll、size、isEmpty、contains、
​ containsAll、iterator

迭代方法:

​ foreach、迭代器

注意事项:
存储过程:
  1. 存储自定义对象时,先会求其值的hash值,根据hash值计算存储的位置(桶)。

  2. 然后与该位置(桶)下的其他对象进行比较(如果没有直接添加),比较时会调用该对象的equals方法 ,如果相等就不添加该对象,如果没有重写hashcode和equals方法,会调用父类默认的方法。

  3. 那何时重写呢?比如:当我们需求是,前两个对象的属性相同 我们觉得是同一个对象 此时要重写。

所以根据我们的需求选择是否重写。

TreeSet:

底层:

树 红黑树 / 二叉树 / 平衡树

优缺点:

维护数据的大小 (有序) ,添加速度和删除速度高于ArrayList 比其他的都低
查询速度高于List 低于Hash。
如果对于存储的数据有 排序的要求,那么首选TreeSet。

常见方法:

​ 同Set,多了一些针对于排序元素的操作 first last floor ceiling higher lower

迭代方法:

​ foreach、迭代器

注意事项:

​ 如果存储的元素需要按照指定的需求进行排序,创建TreeSet对象时 指定比较器。
​ 如果存在的元素是自定义对象:
​ 1:要么自定义对象的所属类 实现了内部比较器Comparable接口 重写compareTo方法
​ 2:要么创建TreeSet对象是 指定外部比较器Comparetor接口 重写compare方法
set中每个元素存储的时候 都是存储在一个map集合中 map集合的键是set中的元素, map中的值是自动添加的一个默认值

HashMap:

底层:

(1.7之前jdk版本) 数组+链表 (1.8+jdk版本)数组+链表+红黑树

优缺点:

添加、删除、修改效率都很高

注意:
存储过程:
  1. 存储自定义对象时,先会求其键的hash值,根据hash值计算存储的位置(桶)。

  2. 然后与该位置(桶)下的其他对象进行比较(如果没有直接添加),比较时会调用该对象的equals方法 ,如果相等就填充该对象的value值,如果没有重写hashcode和equals方法,会调用父类默认的方法。

  3. 那何时重写呢?比如:当我们需求是,前两个对象的属性相同 我们觉得是同一个对象 此时要重写。

所以根据我们的需求选择是否重写。

TreeMap:

底层:红黑树
优缺点: 维护数据的大小 (有序) ,添加速度和删除速度高于ArrayList 比其他的都低
查询速度高于List 低于Hash。
如果对于存储的数据有 排序的要求,那么首选TreeMap。
如果存储的元素需要按照指定的需求进行排序,创建TreeMap对象时 指定比较器。
如果存在的元素是自定义对象:
1:要么自定义对象的所属类 实现了内部比较器Comparable接口 重写compareTo方法
2:要么创建TreeMap对象是 指定外部比较器Comparetor接口 重写compare方法

Arrays:

对象:

针对数组进行的一些操作。

主要方法:

asList -> 数组转集合

sort(排序)、binarySearch(二分查找)、fill(填充)、 copyof (拷贝)、 copyofRange(拷贝指定范围)、toString(打印)

注:
  1. Arrays.asList 返回的是Arrays类中的内部类ArrayList ,而这个类的对象是不允许添加以及删除元素的,也就是返回的集合对象是一个长度不可变的ArrayList。

  2. 使用binarySearch查找元素 一定要先排序 返回的是排序之后的元素索引位置

Collections:

对象:

针对集合进行的一些操作。

主要方法:

toArray -> 集合转数组

binarySearch(二分查找)、sort(排序)、shuffle(乱序)、fill(填充)、 copyof (拷贝)、 copyofRange(拷贝指定范围)、toString(打印)

问题:

Collections通过了一组方法 synchronizedXXX(XXX)

  • 该组方法可以针对传入的集合对象 做线程同步,返回能够同步的线程安全的集合对象
  • 但不一定是线程安全的。 及其特殊的情况下会发生问题
解决办法:

concurrent包下的同步集合实现 同步集合在jdk1.8之后采用分段锁机制完成对于数据的加锁操作 提高效率

注:

使用binarySearch查找元素 一定要先排序 返回的是排序之后的元素索引位置

返回的是排序之后的元素索引位置

Collections:

对象:

针对集合进行的一些操作。

主要方法:

toArray -> 集合转数组

binarySearch(二分查找)、sort(排序)、shuffle(乱序)、fill(填充)、 copyof (拷贝)、 copyofRange(拷贝指定范围)、toString(打印)

问题:

Collections通过了一组方法 synchronizedXXX(XXX)

  • 该组方法可以针对传入的集合对象 做线程同步,返回能够同步的线程安全的集合对象
  • 但不一定是线程安全的。 及其特殊的情况下会发生问题
解决办法:

concurrent包下的同步集合实现 同步集合在jdk1.8之后采用分段锁机制完成对于数据的加锁操作 提高效率

注:

使用binarySearch查找元素 一定要先排序 返回的是排序之后的元素索引位置

标签:迭代,对象,元素,泛型,coll,集合
来源: https://blog.csdn.net/L6_6LXXX/article/details/98106771

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有