专栏首页用代码征服天下java之集合那些事

java之集合那些事

集合概述:

集合和数组都可以保存多个对象,但是数组的长度不可变,集合可以保存数量变化的数据。java中的集合类主要由两个接口派生出,Collection和Map

Collection接口和Iterator接口:

概述:Collection接口是List,Set和Queue接口的父接口

Collection中的主要方法如下:

方法名称

方法概述

boolean add(Object o)

该方法向集合中添加一个元素,成功返回true

boolean addAll(Collection c)

该方法将集合C中的元素添加到指定集合中,成功返回true

void clear()

清除集合中的元素

boolean contains(Object o)

返回集合里是否包含指定元素

boolean containAll(Collection c)

返回集合中是否包含集合c里的所有元素

boolean isEmpty()

返回集合是否为空

Iterator iterator()

返回一个Iterator对象,用于遍历集合里的元素

boolean remove(Object o)

删除集合中的指定元素

boolean removeAll(Coolection c)

从指定集合中删除所包含的c集合中的全部元素

boolean retailAll(Coolection c)

从集合中删除集合中不包含的元素

int size()

返回集合中元素的个数

Object[] toArray()

该方法把集合转化成一个数组

package cn.itcast.collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import org.junit.jupiter.api.Test;


public class CollectionTest {
	
	@Test
	public void testCollection(){
		Collection c=new ArrayList();
		c.add("孙悟空");
		c.add(6);
		System.out.println("c集合的元素个数为"+c.size());
		
		c.remove(6);
		System.out.println("c集合的元素个数为"+c.size());
		
		
		System.out.println("c集合中是否包含孙悟空"+c.contains("孙悟空"));
		c.add("javaee实战");
		System.out.println("c集合中的元素"+c);
		
		Collection books=new HashSet();
		
		books.add("疯狂java讲义");
		books.add("javaee实战");
		
		System.out.println("c集合是否完全包含books集合"+c.containsAll(books));
		
		c.removeAll(books);
		
		System.out.println("c集合中的元素"+c);
		
		c.clear();
		
		System.out.println("c集合中的元素"+c);
		
		books.retainAll(c);
		
		System.out.println("books集合中的元素:"+books);
		
		
	}
	
	
	
	
	@Test
	public void IteratorTest() {
		Collection<String> c=new ArrayList<String>();
		c.add("java编程思想");
		c.add("疯狂java讲义");
		c.add("数据结构与算法");
		Iterator it=c.iterator();
		while(it.hasNext()) {
			String book=(String) it.next();
			System.out.println(book);
			if(book.equals("疯狂java讲义")) {
				it.remove();
			}
			book="测试字符串";
		}
		System.out.println(c);
	}
	

}

上述代码主要展示了Collection的常用方法

testCollection方法的执行结果为:

c集合的元素个数为2
c集合的元素个数为1
c集合中是否包含孙悟空true
c集合中的元素[孙悟空, javaee实战]
c集合是否完全包含books集合false
c集合中的元素[孙悟空]
c集合中的元素[]
books集合中的元素:[]

IteratorTest方法的执行结果为:

java编程思想
疯狂java讲义
数据结构与算法
[java编程思想, 数据结构与算法]

Set集合:

概述:Set集合类似于一个罐子,程序可以依次把多个对象装进这个罐子里面,Set集合通常不能记住元素的添加顺序。Set集合与Collection集合基本相同。

Set三个常用实现类:

HashSet:

概述:

HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。 HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。

特点:

1、不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化 2、HashSet不是同步的,如果多个线程同时访问一个 HashSet,假设有两个或者两个以上线程同时修改了 HashSet集合时,则必须通过代码来保证其同步。 3、集合元素值可以是null

存储数据原理:

HashSet按Hash算法来存储集合中的元素,HashSet的内部存储结构是数组加链表。 HashSet存储元素时首先会根据Hash算法计算出元素在内存中的位置,然后将数据存放在相应的位置。如果该位置已经存放有元素,那么接着调用equals方法判断这两个元素是否相等,如果相等则是同一个元素,不需要存储,如果不相等,说明是不同的元素,此时HashSet会在该位置上产生一个链表来存储这两个元素,此时HashSet的查找性能会降低。

注意点:

在程序中如果重写某个类的hashCode()方法,则同时也应该修改其equals方法。  

hashCode方法的重写规则:

1、在程序运行过程中,同一个对象多次调用 hashCode()方法应该返回相同的值。 2、当两个对象通过 equals方法比较返回tue时,这两个对象的 hashCode()方法应返回相等的值 3、对象中用作 equals方法比较标准的实例变量,都应该用于计算 hashCode值。

LinkedHashSet:

概述:

LinkedHashSet是HashSet的子类,它的功能和HashSet类似,LinkedHashSet也是根据元素的hashCode值来存储,但它同时使用链表维护元素的数据,这样使得元素看起来是以插入的顺序保存的。LinkedHashSet需要使用链表维护数据,因此性能方面要比HashSet低一点。

TreeSet:

TreeSet是SortedSet接口的实现类,正如SortedSet的名字所示,TreeSet可以确保元素处于排序状态。与HashSet相比,TreeSet还有其他几个方法。

方法名称

方法概述

Comparator comparator()

如果 Tree Set采用了定制排序,则该方法返回定制排序所使用的Comparator;如果 TreeSet采用了自然排序,则返回nul

Object first()

返回集合中的第一个元素

Object last()

返回集合中的最后一个元素

Object lower(Object e)

返回集合中位于指定元素之前的元素(即小于指定元素的最大元素,参考元素不需要是集合中的元素)

Object higher(Object e)

返回集合中位于指定元素之后的元素

SortedSet subSet(Object fromElement,Object toElement)

返回此Set的子集合,范围从 fromElement(包含)到 toElement(不包含)。

SortedSet headSet(Object toElement)

返回此Set的子集,由小于 toLerent的元素组成。

SortedSet tailSet(Object fromElement)

回此Set的子集,由大于或等于 fromElement的元素组成。

package cn.itcast.collection;

import java.util.TreeSet;

public class TreeSetTest {
	
	public static void main(String[] args) {
		
		TreeSet nums=new TreeSet();
		nums.add(5);
		nums.add(2);
		nums.add(10);
		nums.add(-9);
		
		System.out.println(nums);
		
		System.out.println(nums.first());
		System.out.println(nums.last());
		System.out.println(nums.headSet(4));
		System.out.println(nums.tailSet(5));
		System.out.println(nums.subSet(2, 8));
	}

}

运行结果:

[-9, 2, 5, 10]
-9
10
[-9, 2]
[5, 10]
[2, 5]

上述代码展示了TreeSet的常用方法

各个Set集合的性能分析:

1、Hash Set和 TreeSet是Set的两个典型实现,到底如何选择 Hash Set和 Tree Set呢? HashSet的性能总是比 TreeSet好(特别是最常用的添加、查询元素等操作),因为 TreeSet需要额外的红黑树算法来维护有Set时,才应该使用 TreeSet,否则都应该使用 HashSet。

2、HashSet还有一个子类:LinkedHash Set,对于普通的插入、删除操作, LinkedHashSet比 HashSet要略微慢一点,这是由维护链表所带来的额外开销造成的,但由于有了链表,遍历 LinkedHashSe会更快。

List集合:

定义:

List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List集合默认按元素的添加顺序设置元素的索引,例如第一次添加的元素索引为0,第二次添加的元素索引为1

list集合中特有的方法:

方法名称

方法描述

void add(int index,Object element)

将元素element插入到集合的指定位置

boolean addAll(int index,Collection c)

将集合c所包含的所有元素插入到List集合的Index处

Object get(int index)

返回集合index索引处的元素

int indexOf(Object o)

返回对象o在List集合中第一次出现的位置索引

int lastIndexOf(Object o)

返回对象o在List集合中最后一次出现的位置索引

Object remove(int index)

删除并返回Index索引处的位置

Object set(int index,Object element)

将index索引处的元素替换成element对象,返回被替换的旧元素。

list的基本使用:

List books=new ArrayList();
books.add(new String("轻量级javaee实战"));
books.add(new String("疯狂java讲义"));
books.add(new String("疯狂Android讲义"));
books.add(new String("疯狂ios讲义"));
		
books.sort((o1,o2)->((String)o1).length()-((String)o2).length());
		
System.out.println(books);
		
books.replaceAll(ele->((String)ele).length());
System.out.println(books);

list的迭代方法:

String[] books = {"轻量级javaee实战","疯狂java讲义","疯狂Android讲义","疯狂ios讲义"};
		
List bookList=new ArrayList();
for(int i=0;i<books.length;i++) {
	bookList.add(books[i]);
}

ListIterator lit=bookList.listIterator();
while(lit.hasNext()) {
	System.out.println(lit.next());
	lit.add("------分隔符-----");
}

System.out.println("========下面开始反向迭代======");
while(lit.hasPrevious()) {
	System.out.println(lit.previous());
}

ArrayList和Vertor:

定义:

ArrayList和Vertor是list的实现类,list中的方法全部都适用于ArrayList和Vertor。ArrayList和Vertor的底层是用数组实现的,ArrayList或 Vector对象使用 initialCapacity参数来设置该数组的长度,当向 ArrayList或 Vector中添加元素超出了该数组的长度时,它们的 initialCapacity会自动增加。

Queue集合:

Queue用于模拟队列这种数据结构,队列是先进先出的数据结构。Queue接口中提供了

queue中的方法:

方法名称

方法描述

void add(Object e)

将元素加入到队列尾部

Object element()

获取队列头部元素,但是不删除

Boolean offer(Object e)

将元素加入到队列尾部,当使用容量有限的队列时,此方法比add效果好

Object peek()

获取头部元素,但是不删除

Object poll()

获取头部元素,并删除该元素

Object remove()

获取头部元素,并删除该元素

LinkedList:

LinkedList也是List的实现类,它与ArrayList不同,LinkedList的底层是基于链表实现。同时,LinkedList还实现了Deque接口,可以被当成双端队列来使用,因此既可以被当成“栈”来使用,也可以被当成队列使用

LinkedList的基本使用:

public class LinkedListTest {
	
	public static void main(String[] args) {
		LinkedList books=new LinkedList();
		books.offer("疯狂java讲义");
		books.push("javaee企业级实战");
		books.offerFirst("疯狂Android讲义");
		for(int i=0;i<books.size();i++) {
			System.out.println("遍历中--"+books.get(i));
		}
		System.out.println(books.peekFirst());
		System.out.println(books.peekLast());
		System.out.println(books.pop());
		System.out.println(books);
		System.out.println(books.pollLast());
		System.out.println(books);
		
	}

}

List集合的性能分析:

  • ArrayList底层是数组实现的,查询速度快,增删速度慢,线程不安全
  • Vertor底层是数组实现的,但是Vertor是线程安全的,所以效率较低
  • LinkedList的底层是链表实现的,增删速度快,查询速度慢,线程不安全

如果经常做增删操作,则推荐使用LinkedList,如果经常使用查询操作,则推荐使用ArrayList,如果两个操作都多,则推荐使用ArrayList

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Redis 与序列化

    序列化只是一种拆装组装对象的规则,那么这种规则肯定也可能有多种多样,比如现在常见的序列化方式有:JDK(不支持跨语言)、JSON、XML、Hessian、Kry...

    业余草
  • 聊聊dubbo的ConfigChangeEvent

    dubbo-2.7.3/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/d...

    codecraft
  • 聊聊dubbo的ServiceBeanExportedEvent

    dubbo-2.7.3/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/conf...

    codecraft
  • servlet中的IllegalStateException

    本文链接:https://blog.csdn.net/u014427391/article/details/97397116

    用户1208223
  • ASP.NET Core 中的 ServiceProvider

    在 ASP.NET Core 中,微软提供了一套默认的依赖注入实现,该实现对应的包为:Microsoft.Extensions.DependencyInject...

    Edison.Ma
  • Netty系列之Netty线程模型

    最近发现极客时间的很多课程中,都穿插到了 Netty,可见 Netty 的重要性。基于此,给大家推荐一下这篇文章!

    业余草
  • QT QJsonObject 与 QJsonArray 中insert()方法 插入值的顺序问题

    本文链接:https://blog.csdn.net/acoolgiser/article/details/99442177

    acoolgiser
  • [译]区域设置更改和 AndroidViewModel 反面模式

    在 ViewModel 中,如果要公开来自资源(字符串、可绘制文件、颜色……)的数据,则必须着重考虑 ViewModel 对象而忽视配置更改,例如区域设置更改。...

    Android 开发者
  • 迭代器模式

    java中的迭代器想必大家都用过,但是大家知道他的性能以及实现原理吗?今天就来介绍一波 实际上foreach封装了迭代器,迭代器又封装了for循环,这样一来,...

    gfu
  • 聊聊dubbo的DubboComponentScanRegistrar

    本文主要研究一下dubbo的DubboComponentScanRegistrar

    codecraft

扫码关注云+社区

领取腾讯云代金券