是否总是需要在HashMap中检查密钥是否存在?
我有一个HashMap,说1000条目,我正在寻求提高效率.如果非常频繁地访问HashMap,那么在每次访问时检查密钥是否存在将导致很大的开销.相反,如果密钥不存在并因此发生异常,我可以捕获异常.(当我知道这种情况很少发生时).这将减少对HashMap的访问一半.
这可能不是一个好的编程习惯,但它会帮助我减少访问次数.或者我在这里遗漏了什么?
[ 更新 ]我在HashMap中没有空值.
我有以下课程.
public class B
{
public A a;
public B()
{
a= new A();
System.out.println("Creating B");
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class A
{
public B b;
public A()
{
b = new B();
System.out.println("Creating A");
}
public static void main(String[] args)
{
A a = new A();
}
}
Run Code Online (Sandbox Code Playgroud)
可以清楚地看到,类之间存在循环依赖关系.如果我试着跑A级,我最终会得到一个StackOverflowError.
如果创建了依赖关系图,其中节点是类,则可以轻松识别此依赖关系(至少对于具有少量节点的图).那为什么JVM不能识别这个,至少在运行时?StackOverflowErrorJVM可以在开始执行之前至少发出警告,而不是抛出.
[更新]某些语言不能具有循环依赖关系,因为这样就不会构建源代码.例如,请参阅此问题和接受的答案.如果循环依赖是C#的设计气味那么为什么它不适用于Java呢?只是因为Java可以(编译循环依赖的代码)?
[update2]最近发现了jCarder.根据该网站,它通过动态检测Java字节代码并在对象图中查找周期来发现潜在的死锁.任何人都可以解释该工具如何找到周期?
我是一名新手程序员,作为我项目的一部分,我必须修改一个包含数百个类的开源工具(用java编写).我必须修改它的重要部分以满足项目的需要.在过去的一个月里,我一直在努力尝试阅读代码,试图找出每个类的功能,并试图从头到尾找出管道.
80%的课程都有不完整/缺失的文件.剩下的20%是构成该工具的通用API的那些.一个月的代码阅读刚刚帮助我理解了基本架构.但我无法弄清楚我需要为我的项目做出的确切更改.有一次,我开始修改部分代码,很快就做了很多改变,我再也记不住了.
一位朋友建议我尝试写下类层次结构.是否有更好的(标准?)方式来做到这一点?
Java中的Collections的size()方法是否有编译器优化?
请考虑以下代码:
for(int i=0;i<list.size();i++)
...some operation.....
Run Code Online (Sandbox Code Playgroud)
每个i都调用size()方法.找出尺寸并重复使用它不是更好吗?(方法调用有开销).
final int len = list.size()
for(int i=0;i<len;i++)
...some operation.....
Run Code Online (Sandbox Code Playgroud)
然而,当我为这两个代码片段计时时,没有显着的时间差异,即使我高达10000000.我在这里错过了一些东西吗?
Update1:我知道除非集合发生变化,否则不再计算大小.但是必须有一些与方法调用相关的开销.编译器是否总是内联这些(参见Esko的答案)?
更新2:我的好奇心得到了进一步的推动.从给出的答案中,我看到好的JIT编译器经常会内联这个函数调用.但他们仍然需要确定该集合是否被修改.我不接受答案,希望有人能给我指点如何由编译器处理.
我有一组字符串[].我想检查这个Set是否包含另一个String [].
Set<String[]> s = new HashSet<String[]>();
s.add(new String[] {"lucy", "simon"});
System.out.println(s.contains(new String[] {"lucy", "simon"}));
Run Code Online (Sandbox Code Playgroud)
但是,打印为false.我猜这是因为只有引用被比较而不是实际的字符串.看来,我唯一的选择是创建一个类,比如Phrase,并实现hashCode()和equals()(使用Arrays.hashCode(...)).
有没有其他方法可以实现我想要的?
我已经读过,通常抽象类不应该在Java中使用Serializable.子类应该是可序列化的(如果需要,可以使用自定义读取,写入方法,例如,当抽象类具有字段时).
这背后的原因是什么?为什么它被认为是糟糕的设计?
Update1:我有一个抽象类,包含一些字段和三个子类.截至目前,我正在使用以下方法.
我已经使用自定义读取,写入方法使所有子类可序列化.在抽象类中,我有以下方法.
void writeFields(ObjectOutputStream out)throws IOException { .... }
void readFields(ObjectInputStream in) throws IOException, ClassNotFoundException{ ... }
Run Code Online (Sandbox Code Playgroud)
在自定义读取,子类中的write方法中,我将这些方法称为(de)序列化抽象类中的字段.这种方法是否正确?或者有更好的方法吗?
更新2:我接受了汤姆的建议并制作了我的抽象类Serializable.(我希望所有子类都是Serializable,我在抽象类中有数据)这是一个旁边,但只是为了完成故事,我正在使用反射来改变Jeremy Manson建议的最终字段.
我有一个使用两种API方法的应用程序.这两种方法都抛出超过五个例外.所以,如果我只是添加一个throws声明,那么它将成为一个超过十个的列表.(我的方法不能处理十个例外中的任何一个)
我读过,抛出一长串异常是一种不好的做法.抛出(伞)异常是一种不好的做法.所以我该怎么做?
编辑:添加选项5.
我需要一个HashSet实现,其中元素是一对整数,
例如.Set s = { {1,2} , {3,4} , {1,4}}.这里的集合有3个元素.
在许多情况下需要这种两个关键的HashSet,我在我的数据库中有一个关系,其中候选键是两列的组合.
有没有一些图书馆已经提供了这个?如果没有这样的实现可用,那么从头开始实现整个数据结构,是否更容易(并且有效?)在Java中扩展HashSet实现?
我的班级有以下构造函数
public MyClass(File f1, File f2, File f3, Class1 c1, Class2 c2, Class3 c3)
{
..........
}
Run Code Online (Sandbox Code Playgroud)
可以看出,它有6个参数.看到这段代码后,我的一位老人说我不应该传递6个参数,而应该传递一个配置对象.
我用这种方式编写代码是因为最近我读到了"依赖注入",它说"类必须要求他们想要什么".所以我认为传递配置对象将违背原则.
我对"依赖注射"的解释是否正确?或者我应该接受老年人的建议吗?