集合复习,深入理解


集合深入理解

集合:用于存储对象,长度可变,可存储不同类型元素

 

框架结构:

Collection:

                   Set:无序,元素不可重复

                             常见子类:

                         | ——HashSet       底层数据结构是哈希表

                                    1, 通过hashCode和equals方法判断对象是否相等

                                     2,如果元素hashCode值不同,不会调用equals方法

                                     3,HashCode值相同才会接着调用equals方法去判断

                         |——TreeSet    底层数据结构是二叉树

  可以对Set集合元素进行排序

                   List:有序,元素可重复,因为该集合有索引

                          |—— ArrayList:底层是数组结构,查询速度快。线程不同步,效率高。初始长度10

                                               可变长度原理:通过不断new数组,长度是50%延长,将原数组copy到新数组,再接着添加新元素

                          |——  LinkedList:底层是链表,增删数度快,查询慢

                          |——  Vector:底层是数组结构。线程同步。延长100%

Java1.6新加入了Deque来代替Vector下的Stack类

 

 

Map     以键值对的形式存值

       |——               HashTable        底层是哈希表结构,不可存入null键null值,线程同步

       |——               HashMap                   底层是哈希表结构,允许使用null值和null键,不同步,效率高

       |——               TreeMap           二叉树,红黑树,不同步,根据键 排序

 

 

Collections

                   工具类,不提供构造函数,不能创建对象,提供static方法对集合进行操作

         如:排序,synchronizedListList()方法,将普通集合包装成线程安全的

 

Set和Map的关系:

         Map的所有键key集中在一起就是一个Set集合,Map集合中有一个keySet()方法,就是返回key所组成的Set集合

         如果将value值看作key的一个附属属性的话,key-value组合起来,也是形成一个Set集合,Map.Entry是一个内部接口

         Set集合如果存入的数据是Map.Entry形式,可以扩展成Map集合

 

 

注意:虽然说集合中存储的是java对象,但是实际上集合中存储的还是对对象的引用

 

如下:

import java.util.ArrayList;
import java.util.List;

class Apple {
	private double weight;

	public Apple(double weight) {
		this.weight = weight;
	}
}

public class ListTest {

	public static void main(String[] args) {
		Apple a = new Apple(1.1);
		Apple a2 = new Apple(2.2);

		List<Apple> list = new ArrayList<Apple>();
		list.add(a);
		list.add(a2);
		// 输出true说明集合中的变量和a引用指向同一个对象
		System.out.println(list.get(0) == a);
	}
}

HashMap和HashSet

向hashSet集合中装东西时,重写equals方法和hashCode方法非常重要

         如下:

import java.util.HashSet;

class Stuff {
	private String id;
	private int age;

	public Stuff(String id, int age) {
		this.id = id;
		this.age = age;
	}

	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj.getClass() == Stuff.class) {
			Stuff s = (Stuff) obj;
			return s.id.equals(id);
		}
		return false;
	}

	public int hashCode() {
		// id唯一,根据返回id属性的哈希值
		return id.hashCode();
	}

	public String toString() {
		return "id:" + id + ",age:" + age;
	}
}

public class HashSetTest {

	public static void main(String[] args) {
		HashSet<Stuff> hs = new HashSet<Stuff>();
		hs.add(new Stuff("ks123", 22));
		// 根据自己写的hashCode方法,此处会判断第二个对象和第一个对象一样,所以不能重复添加
		hs.add(new Stuff("ks123", 23));
		System.out.println(hs);
	}
}

Map和List

   Map集合中的value集中起来就是一个list集合,通过map.values()方法可得到所有value数据

Values()源代码  

	public Collection<V> values(){
//	获取values实例变量
	Collection<v> vs = values;
//	如果vs == null,将返回new Values()对象
	return (vs!=null?vs:new Values());
}

可以看出,返回的并不是list集合对象

 

ArrayLsit和LinkedList

ArrayList的性能总体上来说还是高于LinkedList

在查询元素时,因为ArrayList是数组结构,有索引,比较好找

在删除和增加元素时,ArrayList需要对元素整体移动,所以LinkedList更优

 

迭代器Iterator接口

Java要求各种集合都提供一个iterator()方法,该方法返回一个Iterator用于遍历集合中的元素,至于返回的Iterator到底是哪种实现类,程序并不关心,这就是”迭代器模式”;

如:Iterator和Enumeration两个接口都是迭代器模式的代表作,他们就是“迭代器接口”。

迭代器模式就是指:系统为遍历多种数据列表,集合,容器提供一个标准的“迭代器接口”,这些数据列表,集合,容器就可面向相同的“迭代器接口”编程,通过相同的迭代器接口访问不同的数据列表,集合,容器里的数据。不同的数据列表,集合,容器如何实现这个“迭代器接口”,则交给个数据列表,集合,容器自己完成

 

迭代时删除指定元素

         由于Iterator迭代器只负责迭代,自己并没有保留集合元素,所以通常迭代时不应该删除集合元素,但是java允许通过Iterator的remove()方法删除刚刚迭代的元素。

 

实际上在某些特殊情况下,可以在使用Iterator迭代集合时直接删除集合中某个元素

如下:在迭代倒数第二个元素时,可以删除该元素,但是删除其他元素就会抛异常

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayListRemove {

	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("itheima");
		list.add("cloud");
		list.add("thythm");
		list.add("zhangsan");
		for (Iterator<String> it = list.iterator(); it.hasNext();) {
			String ele = it.next();
			System.out.println(ele);
			if ("thythm".equals(ele)) {
				// 直接删除集合中的倒数第二个元素
				list.remove(ele);
			}
		}
	}
}

对于TreeSet,HashSet等Set集合而言,当使用Iterator遍历他们时,如果正在遍历最后一个集合元素,那么使用Set集合的remove()方法删除集合的任何元素不会引起异常

实际上此时的删除动作已经在遍历操作的范围外了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值