Java中集合概述

集合的作用

用于存储多个同一类型的元素。

集合的分类

集合可以分为单列集合和双列集合。
单列集合的一个元素只由一部分组成,所使用的是Collection接口;而在Collection接口下还有两个子接口:

  1. List接口
  2. Set接口

双列集合的一个元素由K、V两部分组成,使用的是MapMap<K,V>接口。

单列集合Collection接口

在单列集合Collection接口下有一些常用的基本方法,首先创建一个集合并导包:

		Collection<String> list=new ArrayList<>();
  • 新增 :boolean add(E e);
		boolean b=list.add("李华");

返回的布尔值表示新增是否成功,在集合里的新增方法都是默认为true,所以一般不接收返回值。

  • 删除:boolean remove(Object obj);
 		b=list.remove("李华");

true表示删除成功,false表示该元素不存在。

  • 是否包含: boolean contains(Object obj);
		b=list,contains("李华");

true表示集合包含“李华”这个元素,false表示不包含。

  • 是否为空:boolean isEmpty();
		b=list.isEmpty();

true表示集合为空,false表示集合不为空。

  • 集合元素个数:int size();
		int n=list.size();
  • 将集合转成数组:Object[] toArray();
		Object[] object=list.toArray();
  • 将集合转成泛型数组: T[ ] toArray(T[ ] arr);
		String[] s=new String[list.size()];
		list.toArray(s);
		System.out.println(Arrays.toString(s));

根据集合泛型创建对应类型数组,利用此方法进行转换并打印。

  • 删除集合中的所有元素:void clear();
		list.clear();

List接口

List接口下的集合的特点:有索引值、有序、元素可以重复。

List接口下的实现类:

  1. ArrayList:底层是数组,特点:查询快 增删慢,线程不安全,效率高。
  2. LinkedList:底层是链表,特点:查询慢 增删快
  3. Vector(较少使用):和ArrayList类似,特点:线程安全,效率低。

List接口中的方法:

		List<Integer> list=new ArrayList<>();
  • 在指定位置新增:void add(int index,E e);
		list.add(5, 6);

这里的新增方法没有返回值,且有两个参数:索引值和新增元素。上面这行代码表示:在索引值为5处新增元素6.

  • 删除指定索引值位置的元素:E remove(int index);
		Integer n=list.remove(0);

删除索引值为0处的元素,返回被删除的元素。

  • 获取指定索引值位置的元素:E get(int index);
		n=list.get(2);

获取索引值为2处的元素。

  • 替换:E set(int index,E e);
		n=list.set(0, 1);

将索引值为0处的元素替换为1,返回被替换的元素。

  • 截取:List subList(int beginIndex,int endIndex);
		List<Integer> list1=list.subList(1, 4);

将list集合中,从索引值为1开始,至索引值为3的元素截取到新的集合list1中。

  • 获取元素首次出现的索引值:int indexOf(Object o);
		int i=list1.indexOf(4);

如果没有该元素,则返回-1;

  • 获取元素最后一次出现的索引值:int lastIndexOf(Object o);
		i=list1.lastIndexOf(5);

Set接口

Set接口下的集合的特点:没有索引值,元素不可以重复。
Set接口下的实现类:

1.HashSet:无序。底层是哈希表:数组+链表+红黑树。
2.LinkedHashSet:有序。链表+哈希表。
3.TreeSet:可排序。红黑树。

Set集合中不能新增相同的元素。

	Set<String> set=new HashSet<>();
		set.add("胡歌");
		set.add("万茜");
		set.add("易烊千玺");
		set.add("易烊千玺");//值相同时,不能新增
		
	System.out.println(set);//无序:[易烊千玺, 胡歌, 万茜]

可以看到,set集合新增了4个元素,其中有一个元素是重复的,从输出内容看到:set中只有3个元素,说明重复元素没有新增成功;而且可以看到HashSet的输出顺序和新增顺序是不一样的,说明HashSet是无序的,注意这里的无序指的是输出顺序和新增时不一定相同。

同样的,我们来看一下LinkedHashSet:

	Set<String> set1=new LinkedHashSet<>();
		
		set1.add("胡歌");
		set1.add("万茜");
		set1.add("易烊千玺");
		boolean b=set1.add("易烊千玺");//值相同时,不能新增
		
		System.out.println(b);//false
		System.out.println(set1);//有序:[胡歌, 万茜, 易烊千玺]

同样的新增内容,LinkedHashSet的输出顺序和新增顺序是一样的,且重复元素也没有新增成功。

如果新增元素是自定义类型的成员变量,需要判断新增元素是否相同:

	1.计算新增元素的哈希值(十进制的地址值),调用hashCode();//Object的方法。
	2.通过哈希值%数组长度,去确定元素新增的索引值位置
		如果该位置没有元素:直接新增
		如果该位置有元素:判断这两个元素是否相同
			如果不相同:挂到最后一个元素下面
			如果相同:不新增
	3.判断是否相同的标准:
				比较哈希值相同 && (地址值相同 || equals相同)

如果认为成员变量的值相同,就为同一个元素,则需要覆盖重写hashCode方法和equals方法才能实现新增。
TreeSet集合比较特殊,它在进行新增元素的时候,泛型必须是Comparable类型。

  • 创建Comparator类型的对象
		Comparator<E> c = new Comparator<E>() {
		public int compare(E t1, E t2) {
						/*
						 * 	升序:
						 * 		参数1-参数2
						 * 	降序:
						 * 		参数2-参数1
						 */
				int result ;
				return result;
			}
		}
  • 实现Comparable接口,重写 compareTo方法
	public int compareTo(E o) {
		//升序
		//int result = this.成员变量-o.成员变量;
				
		//降序
		int result = o.成员变量-this.成员变量;
		return result;
		
	}

通过这两种方式可以根据需求对元素进行排序。

双列集合

Map<K,V>特点:

  1. 一个元素是有一个K,一个V两部分组成
  2. K V可以是任意的引用数据类型
  3. 一个K对应唯一的一个V、K不能重复

Map<K,V>常用实现类:

  • HashMap:底层是哈希表,无序,线程不安全,效率高。
  • LinkedHashMap:底层是链表+哈希表,有序。
  • TreeMap:底层是红黑树,可排序。
  • Hashtable:线程安全,效率低,K和V不可以为null。

Map<K,V>常用方法:

  • 新增:V put(K k,V v);
	Map<String,Integer> map=new HashMap<>();
		Integer v=map.put("胡歌", 39);
		System.out.println(v);//null
		v=map.put("胡歌", 20);
		System.out.println(v);//39

如果K不存在,则返回null;如果K存在,则新的V替换旧的V,返回被替换的V。

-删除: V remove(Object key);

		v=map.remove("李四");
		System.out.println(v);//38
		
		v=map.remove("张三");
		System.out.println(v);//null

根据key删除整个元素,返回被删除元素的V;如果Key不存在,则返回null。

  • 获取:V get(Object key);
		v=map.get("胡歌");
		System.out.println(v);//20

根据key获取V,如果key不存在则返回null。

  • 包含key:boolean containsKey(Object key);
  • 包含value: boolean containsValue(Object value);
		boolean b=map.containsKey("胡歌");
		b=map.containsValue(36);
  • 获取所有的K:Set keySet();
  • 获取所有的V:Collection values();
		Set<String> key=map.keySet();
		Collection<Integer> values=map.values();

集合的遍历

集合的遍历可以通过迭代器Iterator实现:

		Collection<String> c=new ArrayList<>();
		
			c.add("胡歌");
			c.add("易烊千玺");
			c.add("朱一龙");
			System.out.println(c);
			
			//获取迭代器对象
		Iterator<String> ite=c.iterator();
		while(ite.hasNext()) {
			String s=ite.next();
			System.out.println(s);
				
			//通过迭代器进行新增
			if(s.equals("易烊千玺")) {
				ite.remove();
				}
			}

需要注意的是:在利用迭代器进行遍历的时候,要先利用hasNext()方法判断下一个是否有元素,如果为true则继续进行,利用next()获取下一个元素,进行遍历;通过迭代器遍历集合的时候,不能通过集合对象增、删元素,如果要删除可以通过迭代器对象的删除方法删。

还有一种方法:增强for循环。增强for循环的底层是迭代器,但是其形式较为简单:

			//增强for循环
			for(String name:c) {
				System.out.println(name);
			}

那么对于双列集合如何实现遍历呢?需要将双列集合转成单列集合,具体有两种方法:
第一种:获取所有的K,通过K再获取V。

	Map<String,Double> map = new HashMap<>();
		map.put("张三", 90.0);
		map.put("张三丰", 99.0);
		map.put("李四", 90.0);
	
		//获取所有的K
		Set<String> key=map.keySet();
		System.out.println(key);
		//遍历
		for(String k:key) {
			//根据key获取V
			Double v=map.get(k);
			System.out.println(k+"--"+v);
		}

第二种:通过Entry<K,V>接口进行实现:

		Set<Entry<String,Double>> entry=map.entrySet();
		Iterator<Entry<String, Double>> iterator = entry.iterator();
		while(iterator.hasNext()) {
			Entry<String, Double> e=iterator.next();
			String k=e.getKey();
			Double value=e.getValue();
			System.out.println(k+"--"+value);
		}

转成单列集合后就可以使用迭代器和增强for循环进行遍利了。
以上就是我对集合的整理。

 

  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值