JAVASE(十四) 集合: 数组和集合CollectionIteratorListSetMap

Posted 维宇空灵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVASE(十四) 集合: 数组和集合CollectionIteratorListSetMap相关的知识,希望对你有一定的参考价值。

个人博客网:https://wushaopei.github.io/    (你想要这里多有)

1、数组和集合

1.1 内存中对数据进行存储和管理的“容器”:数组,集合

1.2 数组存储的特点和缺点

特点:

  1. 数组一旦创建成功,长度不可变
  2. 元素存储的类型就是数组声明时的类型。

缺点:

  1. 数组的长度不可变
  2. 数组的API属性比较少,比如没有  增,删,改,插 等...
  3. 存储的元素是序的可重复的,对无序的不可重复的无能为力。

集合存储的优点:

  1. 长度可变
  2. 底层的数据结构比较丰富。比如:数组,链表,红黑树
  3. 集合的API比较丰富,比如 增,删,改,查,插等
  4. 对数据的存储方式支持也比较多,比如序可重复,无序不可重复。

2、Collection接口

2.1 Java 集合概述

Java 集合可分为 Collection 和 Map 两种体系

2.2 单列集合框架结构:Collection

继承树图:

概述:

  • Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
  • JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)实现。
  • 在 Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理;从 JDK 5.0 增加了泛型以后,Java 集合可以记住容器中对象的数据类型。

2.3 Collection接口常用方法:

3、Iterator接口

3.1  遍历Collection的两种方式:

  第一种 增强for循环
  第二种 Iterator接口

3.2 java.utils包下定义的迭代器接口:Iterator

  1. 作用:遍历集合中的元素
  2. 如何获取实例:集合的对象.iteraotr()
  3. 常用方法:

         hasNext() : 判断是否还下一个元素
         next() :①指针下移 ②返回指针指向的元素

    4.举例:

 //获取Iterator实现类的对象
  Iterator iterator = c.iterator();
  while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

   5.图示说明:

  • Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。
  • 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。
  • Iterator 仅用于遍历集合,Iterator 本身并不提供承装对象的能力。如果需要创建 Iterator 对象,则必须有一个被迭代的集合。

                  

3.3 Iterator接口的方法

在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常。

3.4 增强for循环:(foreach循环)

格式:
	for(元素的类型  临时变量 : 集合、数组的对象){
        }

遍历集合:

Collection c = new ArrayList();
            c.add("gg");
            c.add("jj");
            c.add("dd");
            c.add("mm");
        
        for(Object obj : c){
            System.out.println(obj);
        }

遍历数组:

        String[] names = {"小泽泽","小圆圆","小玲玲"};
		for(String str : names){
			System.out.println(str);
		}

4、Collection子接口-List

4.1 存储的数据特点:存储的元素是序的且可重复的

4.2 常用方法:

        

List接口的常用实现类:

           |-------ArrayList : 主要实现类  线程不安全

           |-------LinkedList : 

           |-------Vector :     线程安全

4.3 [ 面试题 ] ArrayList,LinkedList,Vector的区别是什么?

三者都是List的实现类,存储的元素都是有有序的可重复的。
 ArrayList : List的主要实现类底层是一个数组,查找快,增删慢。线程不安全的效率高。
 LinkedList : 底层是一个双向链表,查找慢,增删快
 Vector :古老的实现类,底层是一个数组,查找快,增删慢。线程安全的效率低。

4.4 存储的元素的要求:自定义类必须重写equals方法

4.5 ArrayList

(1)ArrayList构造器的说明:

        new ArrayList() : 底层创建一个长度为10的数组
        new ArrayList(int initialCapacity) : 创建一个长度为initialCapacity的数组

(2)如何向ArrayList中添加数据?

当我们创建一个空参构造器的ArrayList的对象时,底层会为我们创建一个长度为10的数组,当我们向容器中添加第11个元素时,底层会进行扩容,扩容为原来的1.5倍(创建一个长度为原来的1.5倍的数组,同时将原有的数据复制到新的数组中)。

4.6 案例:

public static void main(String[] args) {
	List<Integer> list = new ArrayList<Integer>();
	list.add(1);
	list.add(2);
	list.add(3);
	updateList(list);
	System.out.println(list);
}

private static void updateList(List<Integer> list) {
	list.remove(new Integer(2));
	//list.remove(2);
}

5、Collection 子接口-Set

5.1 存储的数据特点:存储的元素是无序的且不可重复

Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法

5.2 HashSet元素添加方式:

当我们向集合中添加元素时,会先调用该元素的hashCode方法来决定元素存放的位置。如果该位置没有其它元素则直接存放。如果该位置已经有其它元素,则调用该元素的equals方法进行比较。

如果返回值为true则认为这两个元素是相等的则不能再存放。如果返回值是false则以链表的形式存放该数据。(jdk1.8如果该链表位置上的元素到达8个时则改成红黑树的形式存放数据。

HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。

5.3常用方法:没额外增加其它的方法

5..4常用实现类:

    |-----HashSet : 是Set的主要实现类 , 线程不安全

 	    |-----LinkedHashSet : 继承了HashSet底层实现原理和HashSet一样。除此之外还维护了一张链表用来记录元素存放的顺序。那么就可以按照元素存放的顺序进行遍历。

    |-----TreeSet  : 可以对元素进行排序

5..5存储元素所在类的要求:

HashSet,LinkedHashSet : 自定义类需要重写equalshashCode方法

TreeSet : 自定义类实现Comparble接口,或者 创建一个Compartor接口实现类的对象

5..6TreeSet的使用:

说明:

  1. 可以用来对元素进行排序
  2. TreeSet的底层数据结构是红黑树
  3. TreeSet元素的类型必须是同一类型

5.7 思考?

  1. 如果即自然排序又定制排序谁起作用? 定制排序
  2. 自然排序和定制排序哪个更好? 定制排序更灵活

自然排序 :

  1. 自定义类实现Comparable接口
  2. 重写comparTo方法
  3. 在comparTo方法中进行相关属性的比较
  4. 向集合中添加元素

定制排序 :

  1. 创建一个Comparator实现类的对象
  2. 重写compare方法
  3. 在compare方法中进行相应的属性的比较
  4. 将Comparator实现类的对象作为实参传入给TreeSet的构造器中
  5. 向集合中添加数据

5.8 LinkedHashSet的使用说明:

继承了HashSet底层实现原理和HashSet一样。除此之外还维护了一张链表用来记录元素存放的顺序。那么就可以按照元素存放的顺序进行遍历。

5.9 HashSet的实现原理

当我们向集合中添加元素时,会先调用该元素的hashCode方法来决定元素存放的位置。如果该位置没有其它元素则直接存放。如果该位置已经有其它元素,则调用该元素的equals方法进行比较。

如果返回值为true则认为这两个元素是相等的则不能再存放。如果返回值是false则以链表的形式存放该数据。(jdk1.8)如果该链表位置上的元素到达8个时则改成红黑树的形式存放数据。

 

 

 

6、Map接口(双列结合)

继承关系树:

            

6.1 存储数据特点:存储的是键值对

说明:

  1. Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value
  2. Map 中的 key 和  value 都可以是任何引用类型的数据
  3. 可以把Map中所有的key看成是Set的集合,无序的且不可重复的 ---> 要求key中存放自定义类的对象必须重写equals和hashCode方法
  4. 可以把Map中所有的value看成是Collection的集合,无序的可重复的--> 要求value中存放自定义类的对象必须重写equals方法
  5. 我们可以把键值对看成是Entry。Entry是无序的且不可重复的(Entry存放的位置由key来决定)

图示:

           

6.2 常用实现类:

        |-----HashMap            数组+ 链表+红黑树(jdk8以后新增的)

  		|------LinkedHashMap      

        |-----TreeMap

        |-----Hashtable

   	    |----Properties

6.3 常用方法

        

6.4  面试题:

(1) HashMap和HashTable底层实现的区别

相同点:都是以key和value的形式存储;

不同点

  1. HashMap是不安全的;HashTable线程安全的(使用了synchronized关键字来保证线程安全)
  2. HashMap中key和value可以为空;HashTable中value不可以为空

(2)HashMap的底层实现原理?

当我们向HashMap中存放元素(K1,V1)时,会先根据K1的HashCode方法来决定在数组中存放的位置。如果该位置上没有其它元素则直接放入。如果该位置上有其它元素(K2,V2),那么会调用K1的equals方法和K2进行比较。如果返回结果为true说明两个元素的Key(特点:无序且不可重复)值相同。那么V1将会覆盖V2。如果返回结果为false,那么(K1,V1)将以链表的形式存放该内容。如果链表的数量超过8则将链表改成红黑树。

6.5 结构说明

new HashMap() :

通过空参的构造器创建一个HashMap的对象。该对象底层会创建一个长度为16的数组,加载因子为0.75。当集合中的元素的个数超过12时会进行扩容,扩容为原来的2倍。

说明:

  1. HashSet的底层其实就是一个HashMap
  2. LinkedHashSet的底层其实就是一个LinkedHashMap
  3. TreeSet的底层其实就是一个TreeMap

6.7 读取配置文件的操作实现

                //1.创建Properties的对象
		Properties properties = new Properties();
		//2.创建一个文件
		File file = new File("person.properties");
		//3.创建一个文件输入流
		FileInputStream fis = new FileInputStream(file);
		//4.加载流
		properties.load(fis);
		//5.获取文件中的内容
		String username = properties.getProperty("username");
		String password = properties.getProperty("password");
		System.out.println(username + " " + password);
		//6.关流
		fis.close();

6.8 Collections工具类的使用

  • reverse(List):反转 List 中元素的顺序
  • shuffle(List):对 List 集合元素进行随机排序
  • sort(List):根据元素的自然顺序对指定 List 集合元素升序排序
  • sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
  • swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
  • Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
  • Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
  • Object min(Collection)
  • Object min(Collection,Comparator)
  • int frequency(Collection,Object):返回指定集合中指定元素的出现次数
  • void copy(List dest,List src):将src中的内容复制到dest中
  • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所旧值


以上是关于JAVASE(十四) 集合: 数组和集合CollectionIteratorListSetMap的主要内容,如果未能解决你的问题,请参考以下文章

javaSE集合---进度2

基于JavaSE阶段下的集合类汇总

JavaSE_集合(集合简单认识CollectionList)

JavaSE进阶--Collection集合

JavaSE Collection集合

javaSE (十五)对象数组集合(Collection)集合(List)