Java集合有啥用?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java集合有啥用?相关的知识,希望对你有一定的参考价值。
当你事先不知道要存放数据的个数,或者你需要一种比数组下标存取机制更灵活的方法时,你就需要用到集合类。理解集合类
集合类存放于java.util包中。
集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。
集合类型主要有3种:set(集)、list(列表)和map(映射)。 参考技术A 存储数据的作用 参考技术B
数组不是面向对象的,存在明显的缺陷,集合弥补了数组的缺点,比数组更灵活更实用,而且不同的集合框架类可适用不同场合。如下:
数组能存放基本数据类型和对象,而集合类存放的都是对象,集合类不能存放基本数据类型。数组和集合存放的对象皆为对象的引用地址。
数组容易固定无法动态改变,集合类容量动态改变。
数组无法判断其中实际存有多少元素,length只告诉了数组的容量,而集合的size()可以确切知道元素的个数
集合有多种实现方式和不同适用场合,不像数组仅采用顺序表方式
集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性即可实现各种复杂操作,大大提高了软件的开发效率
集:
HashSet: 使用HashMap的一个集的实现。虽然集定义成无序,但必须存在某种方法能相当高效地找到一个对象。使用一个HashMap对象实现集的存储和检索操作是在固定时间内实现的.
TreeSet: 在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap.
列表:
Vector: 实现一个类似数组一样的表,自动增加容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中一样。你也可以用一个迭代器从一个Vector中检索对象。Vector是唯一的同步容器类??当两个或多个线程同时访问时也是性能良好的。
Stsck: 这个类从Vector派生而来,并且增加了方法实现栈??一种后进先出的存储结构。
LinkedList: 实现一个链表。由这个类定义的链表也可以像栈或队列一样被使用。
ArrayList: 实现一个数组,它的规模可变并且能像链表一样被访问。它提供的功能类似Vector类但不同步。
映射:
HashTable: 实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。
HashMap: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。
WeakHashMap: 实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。
TreeMap: 实现这样一个映象,对象是按键升序排列的。
Set 和List都是由公共接口Collection扩展而来,所以它们都可以使用一个类型为Collection的变量来引用。这就意味着任何列表或集构成的 集合都可以用这种方式引用,只有映射类除外(但也不是完全排除在外,因为可以从映射获得一个列表。)所以说,把一个列表或集传递给方法的标准途径是使用 Collection类型的参数。
在 Java 中向 HashMap 添加空键或值有啥用?
【中文标题】在 Java 中向 HashMap 添加空键或值有啥用?【英文标题】:What is the use of adding a null key or value to a HashMap in Java?在 Java 中向 HashMap 添加空键或值有什么用? 【发布时间】:2011-02-26 01:58:04 【问题描述】:HashMap 允许一个空键和任意数量的空值。它有什么用?
【问题讨论】:
“也许问题不在于没有什么在困扰我们,而是我们正在困扰它。” 在 Guava、google 集合中,许多类不允许 null 其背后的原因是 95% 的情况不需要 null 并且它们可以表示错误,可能很难找到。 奇怪的是,ConcurrentHashMap
不支持空键,而 HashMap
支持。
只有 HashMap 允许 null :)
【参考方案1】:
我不确定您要问什么,但是如果您正在寻找一个何时想要使用空键的示例,我经常在地图中使用它们来表示默认情况(即如果给定的键不存在,则应使用):
Map<A, B> foo;
A search;
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
HashMap
专门处理空键(因为它不能在空对象上调用 .hashCode()
),但空值并没有什么特别之处,它们像其他任何东西一样存储在映射中
【讨论】:
那么如果 .hashCode() 在 null 上是不可能的,那么谁来决定 null 键将进入哪个托架? @Pacerier 在HashMap
(putForNullKey
) 中有一个特殊的方法可以处理它;它将它存储在表 0 中
@MichaelMrozek 你的最后一行B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
我想我们可以简单地在搜索键上调用 get 方法,它会得到相同的结果。 B val = foo.get(search);
如果我有什么不对的地方请纠正我吗?
@dheeraj92 如果密钥不存在,您的代码会将val
设置为null
;我的将其设置为 null
映射到地图中的任何内容。这就是重点,我在地图中的 null
键处存储了一个默认的非空值,如果实际键不存在则使用它【参考方案2】:
一个例子是为树建模。如果您使用 HashMap 表示树结构,其中键是父节点,值是子节点列表,则 null
键的值将是根节点。
【讨论】:
【参考方案3】:null
的一个使用示例值 是使用 HashMap
作为可能返回 @ 的昂贵操作(例如调用外部 Web 服务)结果的缓存时987654323@.
将null
值放入映射中,然后您可以区分未对给定键执行操作(cache.containsKey(someKey)
返回false
)和已执行操作但返回的情况null
值(cache.containsKey(someKey)
返回 true
,cache.get(someKey)
返回 null
)。
如果没有 null
值,您将不得不在缓存中放入一些特殊值来指示 null
响应,或者根本不缓存该响应并每次都执行操作。
【讨论】:
【参考方案4】:到目前为止的答案只考虑拥有null
密钥的价值,但问题还涉及any number of null values
。
将值 null
存储在 HashMap 中的键的好处与在数据库等中相同 - 您可以记录具有空值(例如字符串“”)和不具有值(null)。
【讨论】:
【参考方案5】:这是我唯一有点做作的例子,说明null
键可能有用:
public class Timer
private static final Logger LOG = Logger.getLogger(Timer.class);
private static final Map<String, Long> START_TIMES = new HashMap<String, Long>();
public static synchronized void start()
long now = System.currentTimeMillis();
if (START_TIMES.containsKey(null))
LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(null).longValue()) +"ms");
START_TIMES.put(null, now);
public static synchronized long stop()
if (! START_TIMES.containsKey(null))
return 0;
return printTimer("Anonymous", START_TIMES.remove(null), System.currentTimeMillis());
public static synchronized void start(String name)
long now = System.currentTimeMillis();
if (START_TIMES.containsKey(name))
LOG.warn(name + " timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(name).longValue()) +"ms");
START_TIMES.put(name, now);
public static synchronized long stop(String name)
if (! START_TIMES.containsKey(name))
return 0;
return printTimer(name, START_TIMES.remove(name), System.currentTimeMillis());
private static long printTimer(String name, long start, long end)
LOG.info(name + " timer ran for " + (end - start) + "ms");
return end - start;
【讨论】:
如果你试图停止一个不存在的计时器,或者一个已经停止的计时器,那应该是一个错误,而不是被忽略。 @QPaysTaxes - 取决于您的意图。如果您想要一个易于使用的轻量级实用程序,您通常不想要throw Exception
左右。此外,尝试停止不存在或已经停止的计时器并不是调用者通常可以从中恢复的东西。【参考方案6】:
另一个例子:我用它来按日期对数据进行分组。 但有些数据没有日期。我可以将它与标题“NoDate”分组
【讨论】:
【参考方案7】:当映射存储 UI 选择的数据时,空键也很有用,其中映射键表示 bean 字段。
例如,相应的空字段值将在 UI 选择中表示为“(请选择)”。
【讨论】:
以上是关于Java集合有啥用?的主要内容,如果未能解决你的问题,请参考以下文章