Set、Map、List三种集合的差别

  • Post author:
  • Post category:其他


1.集合类型主要有3种:set(集)、list(列表)和map(映射)。

2.三者关系

3.Set

set接口时Collection接口的一个子接口,

是无序的,

set中不包含重复的元素,也就是说set中不存在两个这样的元素a1.equals(a2)结果为true。又因为Set接口提供的数据结构是数学意义上的集合概念的抽象,因此他支持对象的添加和删除。

Set的接口继承Collection接口,而且不允许集合中存在重复项。

TreeSet:在集中以升序对对象排序的集的实现,这意味着从一个TreeSet对象获得第一个迭代器将按照升序来提供对象,TreeSet类使用了一个TreeMap

下面来看一个例子,当需要从一个Set集合中以有序的方式抽取元素时,TreeSet实现会有用处,为了能顺利进行,添加到TreeSet的元素必须是可排序的。

public class Collection_test {

	public static void main(String[] args) {
		
		Set<String> set = new HashSet<String>();
		set.add("xet");
		set.add("jpo");
		set.add("wo");
		set.add("jpo");
		System.out.println(set);

		Set<String> softset = new TreeSet<String>(set);
		System.out.println(softset);
	}
}

可以看到上面的输出是无序的,且没有重复,下面的输出就是按照首字母的顺序进行排序

4.List


List接口继承了Collection接口以定义一个允许重复项的有序集合。

一般有2种List,一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的LinkedList,他并不是为了快速随机访问而设计的,而是具有一套更通用的方法

List最重要的特点就是

:它保证维护元素特定的顺序,

List为Collection添加了很多方法,使得能够向List中间插入语移除元素。

ArrayList:由数组实现的List,允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。

LinkedList:对顺序访问进行了优化,向List中间插入与删除的开销并不大,随机访问则行对较慢,(使用ArrayList代替)还有下列方法:addFirst(),addLast(),getFirst(),getLast(),removeFirst(),romoveLast().这些方法使得LinkedList可以当作堆栈,队列和双向队列使用。

List的一些API的使用:

public class Collection_test {

	
	public static void main(String[] args) {
		
		List l1 = new LinkedList();
		for(int i = 0;i<=5;i++){
			l1.add("a"+i);
		}
		System.out.println(l1);
		//向指定位置加一个字符串
		l1.add(0,"a100");
		System.out.println(l1);
		//替换index=6的位置的字符串
		l1.set(6, "a200");
		System.out.println(l1);
		//取index=2的位置的字符串
		System.out.println(l1.get(2)+"");
		//获得a3的index索引编号
		System.out.println(l1.indexOf("a3"));
		//移除index=1的值
		l1.remove(1);
		System.out.println(l1);
	}
}

List的常用算法举例

		/**
		 * List常用算法举例
		 */
		
		List p1 = new LinkedList();
		List p2 = new LinkedList();
		for(int i = 0; i<=9;i++){
			p1.add("a"+i);
		}
		//打印p1[a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
		System.out.println(p1);
		//随机排列
		Collections.shuffle(p1);
		System.out.println(p1);
		//逆序
		Collections.reverse(p1);
		System.out.println(p1);
		//排序
		Collections.sort(p1);
		System.out.println(p1);
		//折半查找
		System.out.println(Collections.binarySearch(p1, "a5"));
	}

5.set 和List的对比

Collection是集合接口

—Set子接口:无序,不允许存在重复的元素

—List子接口:有序,可以存在重复元素

区别,Collection是集合类

Set 和List的对比:

Set:检查元素效率低下,删除和插入的效率高,插入和删除不会引起元素的位置变化。

List:和数组类似,List可以动态增长,查找元素的效率较高,插入元素和删除元素效率低,因为会引起其他元素位置发生变化。

Set 和 List的具体子类:

Set

—-HashSet:以哈希表的形式存放元素,插入删除速度很快

List:

—-ArrayList :动态数组

—-LinkedList:链表,队列,堆栈

6.Map

Map接口不是Collection接口的继承,而是从自己的用于维护键值对关联的接口层次结构入手,按定义,该接口描述了从不重复的键到值的映射。

一般可以分为三组操作:改变,查询和提供可选视图


Map.Entry 接口


Map



entrySet()

方法返回一个实现

Map.Entry

接口的对象集合。集合中每个对象都是底层

Map

中一个特定的键-值对。

通过这个集合迭代,您可以获得每一条目的键或值并对值进行更改。但是,如果底层

Map



Map.Entry

接口的

setValue()

方法外部被修改,此条目集就会变得无效,并导致迭代器行为未定义。


HashMap

: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。


映射的使用示例:

以下程序演示了具体

Map

类的使用。该程序对自命令行传递的词进行频率计数。

HashMap

起初用于数据存储。后来,映射被转换为

TreeMap

以显示有序的键列列表。

import java.util.*;

public class MapExample {
  public static void main(String args[]) {
    Map map = new HashMap();
    Integer ONE = new Integer(1);
    for (int i=0, n=args.length; i<n; i++) {
      String key = args[i];
      Integer frequency = (Integer)map.get(key);
      if (frequency == null) {
        frequency = ONE;
      } else {
        int value = frequency.intValue();
        frequency = new Integer(value + 1);
      }
      map.put(key, frequency);
    }
    System.out.println(map);
    Map sortedMap = new TreeMap(map);
    System.out.println(sortedMap);
  }
}

结果:

//无序输出:
{prescribed=1, a=1, time=2, any=1, no=1, shall=1, nor=1, peace=1, owner=1, soldier=1, to=1, the=2, law=1, but=1, manner=1, without=1, house=1, in=4, by=1, consent=1, war=1, quartered=1, be=2, of=3}
//有序输出:
{a=1, any=1, be=2, but=1, by=1, consent=1, house=1, in=4, law=1, manner=1, no=1, nor=1, of=3, owner=1, peace=1, prescribed=1, quartered=1, shall=1, soldier=1, the=2, time=2, to=1, war=1, without=1}


1、什么是Iterator

一些集合类提供了内容遍历的功能,通过java.util.Iterator接口。这些接口允许遍历对象的集合。依次操作每个元素对象。当使用 Iterators时,在获得Iterator的时候包含一个集合快照。通常在遍历一个Iterator的时候不建议修改集合本省。


2、Iterator与ListIterator有什么区别?

Iterator:只能正向遍历集合,适用于获取移除元素。ListIerator:继承Iterator,可以双向列表的遍历,同样支持元素的修改。


3、什么是HaspMap和Map?

Map是接口,Java 集合框架中一部分,用于存储键值对,HashMap是用哈希算法实现Map的类。


4、HashMap与HashTable有什么区别?对比Hashtable VS HashMap

两者都是用key-value方式获取数据。Hashtable是原始集合类之一(也称作遗留类)。HashMap作为新集合框架的一部分在Java2的1.2版本中加入。它们之间有一下区别:

● HashMap和Hashtable大致是等同的,除了非同步和空值(HashMap允许null值作为key和value,而Hashtable不可以)。

● HashMap没法保证映射的顺序一直不变,但是作为HashMap的子类LinkedHashMap,如果想要预知的顺序迭代(默认按照插入顺序),你可以很轻易的置换为HashMap,如果使用Hashtable就没那么容易了。

● HashMap不是同步的,而Hashtable是同步的。

● 迭代HashMap采用快速失败机制,而Hashtable不是,所以这是设计的考虑点。


5、在Hashtable上下文中同步是什么意思?

同步意味着在一个时间点只能有一个线程可以修改哈希表,任何线程在执行hashtable的更新操作前需要获取对象锁,其他线程等待锁的释放。


6、什么叫做快速失败特性

从高级别层次来说快速失败是一个系统或软件对于其故障做出的响应。一个快速失败系统设计用来即时报告可能会导致失败的任何故障情况,它通常用来停止正常的操作而不是尝试继续做可能有缺陷的


工作


。当有问题发生时,快速失败系统即时可见地发错错误告警。在Java中,快速失败与iterators有关。如果一个iterator在集合对象上创建了,其它线程欲“结构化”的修改该集合对象,并发修改异常 (ConcurrentModificationException) 抛出。


7、怎样使Hashmap同步?

HashMap可以通过Map m = Collections.synchronizedMap(hashMap)来达到同步的效果。


8、什么时候使用Hashtable,什么时候使用HashMap

基本的不同点是Hashtable同步HashMap不是的,所以无论什么时候有多个线程访问相同实例的可能时,就应该使用Hashtable,反之使用HashMap。非线程安全的数据结构能带来更好的性能。

如果在将来有一种可能—你需要按顺序获得键值对的方案时,HashMap是一个很好的选择,因为有HashMap的一个子类 LinkedHashMap。所以如果你想可预测的按顺序迭代(默认按插入的顺序),你可以很方便用LinkedHashMap替换HashMap。反观要是使用的Hashtable就没那么简单了。同时如果有多个线程访问HashMap,Collections.synchronizedMap()可以代替,总的来说HashMap更灵活。


说在结尾

我的很多知识都是在how2j学习的,里面的知识也是非常系统的,推荐给大家:

https://how2j.cn/p/7279



版权声明:本文为lmarster原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。