我是C++出身但是从事Java多年,下面将是通过java来实现算法考察点任何算法基本上都可以通过暴力枚举来解决,但那仅仅是理论上。解决问题不仅要考虑理论最终还得取决于硬件和时间的支持。...基于上面两个痛点,我决定取消Hash表的引入。上面说了本题的考点是Hash表,但是并不意味着必须使用Hash表来实现是最优的。所谓条条大路通罗马实现是有很多种的,善于利用周遭的环境是我们人类的本能。...优化落地既然是查找重复数据如果是有序的数组的话只需要逐个对相邻的两个进行比较就可以了。...而且我们需要逐个进行比较,逐个比较在时间上应该是比较耗时的。基于上面逐个比较,笔者这里再次进行优化。将进行跳位比较跳位就避免了逐个比较,将比较的次数控制下来。...本次的升级实际上是失败的,充其量就是逐位相邻比较的一种变形。但是本次的变形却引入另外一个概念---跳位交换最终升级升级点其实仔细思考下为什么跳位寻址比较没有逐位相邻比较有什么显著的提升呢。
上节我们提到,如果需要一个Map的实现类,并且键的类型为枚举类型,可以使用HashMap,但应该使用一个专门的实现类EnumMap。 为什么要有一个专门的类呢?...为什么需要这个参数呢?没有这个,EnumMap就不知道具体的枚举类是什么,也无法初始化内部的数据结构。...但,直接使用数组需要自己维护数组索引和枚举值之间的关系,正如枚举的优点是简洁、安全、方便一样,EnumMap同样是更为简洁、安全、方便,它内部也是基于数组实现的,但隐藏了细节,提供了更为方便安全的接口。...Object val : vals) if (value.equals(val)) return true; return false; } 遍历值数组进行比较...下一节,我们来看枚举类型的Set接口的实现类EnumSet,与之前介绍的Set的实现类不同,它内部没有用对应的Map类EnumMap,而是使用了一种极为高效的方式,什么方式呢?
---- HashSet详解 对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素。所以如果对HashMap比较熟悉,那么HashSet是so easy!!...更加确切的讲应该是要满足这种关系才能返回true:(o==null ? e==null : o.equals(e))。底层调用containsKey判断HashMap的key值是否为空。...后记: 由于HashSet底层使用了HashMap实现,使其的实现过程变得非常简单,如果你对HashMap比较了解,那么HashSet简直是小菜一碟。...它是使用元素的自然顺序对元素进行排序,或者根据创建Set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。...5、clone:返回 TreeSet 实例的浅表副本。属于浅拷贝。 ? 6、comparator:返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。
而在某些情况下,如果我们需要Map集合里的元素有序,那么HashMap是不能满足我们的要求的。 那么有没有有序的Map集合呢?...其实LinkedHashMap与HashMap区别不大,也是通过计算键的hash值,映射到hash表中,那么LinkedHashMap是如何实现有序的呢?...使用accessOrder来标记使用哪种排序方式,accessOrder==true时,表示使用访问排序,默认为false;注意:LinkedHashMap的有序不是key或value的自然顺序。...TreeMap的插入: put(): 如果Comparator 为空,会使用key进行比较,按照从小到大的次序插入到红黑树中。...如果Comparator 不为空,则根据Comparator来进行比较。
我们使用枚举,很多场合会用到该枚举的字串符表达,而上述的实现中只能得到一个数字,不能直观地表达该枚举常量的含义。当然也可用 String 常量,但是又会带来性能问题,因为比较要依赖字符串的比较操作。...使用 enum 来表示枚举可以更好地保证程序的类型安全和可读性。 enum 是类型安全的。除了预先定义的枚举常量,不能将其它的值赋给枚举变量。这和用 int 或 String 实现的枚举很不一样。...大多数程序员应优先使用toString方法,因为toString方法可能返回一个更加用户友好的名称。 方法主要用于特殊情况, 其中正确性取决于获取确切名称,该名称在不同版本之间不会有所不同。...* * @param other 要与此对象进行相等性比较的对象。 * @return 如果指定的对象等于此枚举常量,则返回true。...所以,创建一个enum类型是线程安全的。 为什么用枚举实现的单例是最好的方式 1. 枚举写法简单 2.
不通过 new,而是用一个静态方法来对外提供自身实例的方法,即为我们所说的静态工厂方法(Static factory method)。...其中开篇第一条就是『考虑使用静态工厂方法代替构造器』,关于其原因,作者总结了 4 条(第二版),我们先来逐个看一下。...: Map map = new HashMap(); 不过自从 java7 开始,这种方式已经被优化过了 —— 对于一个已知类型的变量进行赋值时,由于泛型参数是可以被推导出...—— 要避免这种错误,使用枚举来代替常量值是常见的方法之一,当然如果不想用枚举的话,使用我们今天所说的主角静态工厂方法也是一个很好的办法。...插一句: 实际上,使用枚举也有一些缺点,比如增大了调用方的成本;如果枚举类成员增加,会导致一些需要完备覆盖所有枚举的调用场景出错等。
,我们使用Rust来实现。...先理清思路,首先根据题目,不使用重复元素,假设只存在一个正确答案,最简单直接的思路,就是两层循环,逐个相加判断是否等于target的值,如果相等,则返回相应的索引数字。...将目的抽象化就是“x + y = target”,求x和y的索引,可以看做就是求x和y,目前是通过两个数字相加再与目标比较的方法,这样就需要循环出x和y的值,那么我们反过来考虑,y = target -...x 通过减法来消除一个未知变量,而这个y一定是x遍历过的值或还未遍历到的。...所以需要将x遍历过的值进行保存,很容易可以想到读写时间复杂度最低的就是HashMap,不过HashMap的get方法返回值是一个之前没有提到过的枚举 Option类型,这个类型有两个枚举值Some
在使用HashSet或者HashMap集合中,比较两个对象是否相等时,会先调用hashCode()比较,如果hashCode()相等,则会继续调用equals()比较,equals()也相等才会认为是同一个对象...(为什么初始值是2的n次方,为什么负载因子取0.75,这两个问题可以网上找资料看看,这里就不详述了) 简述一下HashMap的扩容机制?...如何进行日期的转换? 使用SimpleDateFormat类进行String和Date之间的转换。 如何获取上一年的今天的日期? 使用Calendar对象。...这个问题通常可以使用版本号来解决。 CPU开销过大。在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给CPU带来很到的压力。...你有多少种不同的方法可以爬到楼顶呢?
作为集合类型比较通用的一个定义,它主要用在一些需要比较高级别抽象的地方。比如说我们需要可以对所有集合类型进行通用操作。 ...(6)获取此collection的迭代器、iterator() - 用于遍历集合(此迭代器只能遍历集合,不能对集合进行修改,否则会报并发 修改异常-ConcurrentModificationException...使用key、value键值对的形式进行访问的集合类 ? ...TreeMap不允许null作为key,要不然怎么比较呢? ...6)EnumMap类 EnumMap是一个与枚举类一起使用的Map实现。它的key必须是单个枚举类的枚举值。EnumMap不允许使用null作为key,但可作为value。
那么Integer为什么是-127~128进行缓存了呢?....getCode().equals(inputBizCode)) 那么这个又是为什么呢?...hashCode方法,p1和p2的hashCode方法返回的哈希码不同,导致它们在HashMap中被当作不同的键,因此无法正确地获取到值。...这是因为散列集合使用对象的hashCode值来确定它们在内部存储结构中的位置。 问题3:== 在哪些情况下比较的是对象内容而不是引用? 答案:在Java中,== 运算符通常比较的是对象的引用。...字符串常量池:对于字符串字面值,Java使用常量池来存储它们,因此相同的字符串字面值使用==比较通常会返回true。
内存对齐这么复杂,为什么要有这东西呢?难道是为了给自己添加麻烦吗? 当然不是! ...2、位段的空间上是按照需要以四个字节或者一个字节(char)的方式来开辟的。 3、位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。...那么空间是如何开辟的呢? 我们可以知道,10转化为二进制的代码是1010,可是 只能用3个比特位,所以取出010来存储,12二进制是1100,取用四个比特位,全部放进去,而存储的时候是四个。...所以地址中的存储是,620304,也验证了我们的猜想,而且我们也可以知道,位段在一个字节中浪费的位置,下一个变量如果不够的话不会继续使用,而是开辟新的字节并在其中存储。...枚举的好处 明明可以用 #define 代替,为什么还要用枚举呢? 1、增加代码的可读性和可维护性。 2、和 #define 定义的标识符相比,枚举有类型检查,更加的严谨。
,这是为什么呢?...,我们使用两种解决方案,一种是HashMap,一种EnumMap,虽然都统计出了正确的结果,但是EnumMap作为枚举的专属的集合,我们没有理由再去使用HashMap,毕竟EnumMap要求其Key必须为...null,虽说是枚举专属集合,但其操作与一般的Map差不多,概括性来说EnumMap是专门为枚举类型量身定做的Map实现,虽然使用其它的Map(如HashMap)也能完成相同的功能,但是使用EnumMap...会更加高效,它只能接收同一枚举类型的实例作为键值且不能为null,由于枚举类型实例的数量相对固定并且有限,所以EnumMap使用数组来存放与枚举类型对应的值,毕竟数组是一段连续的内存空间,根据程序局部性原理...],这也是为什么EnumMap能维持与枚举实例相同存储顺序的原因,我们发现在对vals[]中元素进行赋值和返回旧值时分别调用了maskNull方法和unmaskNull方法 //代表NULL值得空对象实例
一、ConcurrentHashMap 概述 ConcurrentHashMap 是 HashMap 的线程安全版本,其内部和 HashMap 一样,也是采用了数组 + 链表 + 红黑树的方式来实现。...2、JDK1.8 中结构 JDK1.8 的实现已经摒弃了 Segment 的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 Synchronized 和 CAS 来操作,...---- 四、相关知识点 1、 JDK 1.8 中为什么要摒弃分段锁 很多人不明白为什么Doug Lea在JDK1.8为什么要做这么大变动,使用重级锁synchronized,性能反而更高,原因如下:...这就 2、为什么 key 和 value 不允许为 null 在 HashMap 中,key 和 value 都是可以为 null 的,但是在 ConcurrentHashMap 中却不允许,这是为什么呢...本身放的就是 null,还是说这个 key 值根本不存在,这会引起歧义,如果在非并发编程中,可以进一步通过调用 containsKey 方法来进行判断,但是并发编程中无法保证两个方法之间没有其他线程来修改
不建议使用。...1 //懒汉式单例模式 2 //比较懒,在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢 3 private static LazySingleton intance...因为当JVM从内存中反序列化地"组装"一个新对象时,自动调用 readResolve方法来返回我们指定好的对象 4.5 枚举单例 枚举反序列化不会生成新的实例 优点:线程安全 缺点:枚举耗内存,能不用枚举就不用...可以看出,会自动生成 ACC_STATIC, ACC_FINAL这两个修饰符 枚举类型为什么是线程安全的?...4.6 使用容器实现单例模式 在程序的初始化,将多个单例类型注入到一个统一管理的类中,使用时通过key来获取对应类型的对象,这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行操作
如果为空,则进入同步代码块,02行又进行一次检查。 双重检查就是现实if判断、获取类对象锁、if判断。...所以,上面说的双重检查锁的方式,通过反射,还是会存在潜在的风险。怎么办呢? 在《Effect java 》这本书中,作者推荐使用枚举来实现单例模式,因为枚举不能被反射。...如果此时面试官,为什么枚举不能被反射呢? 为什么枚举不能被反射呢?...,为什么枚举不让反射的原因。...,那为什么呢?
我们可以使用iterator()方法从Collection中获取迭代器实例。在Java Collections Framework中,迭代器代替了枚举。...枚举的速度是Iterator的两倍,并且使用的内存更少。枚举是非常基本的,适合基本需求。...10、为什么Iterator没有不移动光标就直接获取下一个元素的方法? 可以在当前Iterator接口的顶部实现它,但是由于很少使用它,因此将它包含在每个人都必须实现的接口中没有意义。...当我们put通过传递键值对来调用方法时,HashMap使用带有哈希值的Key hashCode()来查找存储键值对的索引。...当我们尝试从HashMap中获取价值时,也会使用这些方法。
,包装类型比较使用equals a == c true a 自动拆箱为int 类型进行值比较 Integer f1 = 100,f2 = 100, f3 = 150, f4 = 150;...HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不 同) 而是按照哈希值来存的所以取数据也是按照哈希值取得。...元素的哈希值是通过元素的 hashcode方法来获取的, HashSet首先判断两个元素的哈希值,如果哈希值一样,接着会比较 equals方法 如果 equls结果为true ,HashSet就视为同一个元素...这也就解释了 HashMap 的长度为什么是2的幂次方。...到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。
(uppercase(&s), "HELLO"); } 上面 uppercase 方法的参数类型 明明是 &str,但现在main函数中实际传的类型是 &String,为什么编译可以成功呢?...那现在问题来了,什么时候使用 AsRef 呢?为啥不直接用 &T ?...比较简单的情况。 其实在标准库文档中给出的 HashMap 示例已经说明的很好了。我来给大家翻译一下。...因为 HashMap 要对 key 进行 hash计算 和 比较,所以必须要求 不管是 Key 的自有值,还是引用,在进行 hash计算和比较的时候,行为应该是一致的。...> Option where K: Hash + Eq { // ... } // 使用 get 方法通过 key 来获取对应的值,则可以使用 key
使用fatalError()函数,会毫无条件的终止你的应用程序,用起来也是比较简单的,就是一个函数的调用。下方这个Demo一目了然呢,在此就不做过多赘述了。 ? 2. ...最后就是使用do-catch处理异常了,在catch中对绑定的错误代码和错误原因进行了获取,并且通过where子句进行了错误代码的筛选。...2.使用结构体为错误处理添加Reason 在上面的内容中,使用枚举遵循ErrorType协议的方式定义了特定的错误类型。接下来我们将使用结构体来遵循ErrorType协议,为错误类型添加错误原因。...三、在错误处理中使用内置关键字 1.初探这些内置关键字 在Swift中提供了一些内置关键字(__FILE__, __FUNCTION__, __LINE__等)来获取上下文信息,在本篇博客的第三部分,将会给出如何在我们的错误处理中使用这些内置关键字...在下方的输出结果中,文件名我们可以看到是这并不是确切的文件名,因为我们是在Playground中使用的,并且不是确切的Swift源文件,所以获取不到确切的文件名。 ?
领取专属 10元无门槛券
手把手带您无忧上云