anagram-go-java:Go和Java并排使用-​​旧的编码器回头看Java

昨天,我摸索了一个简单的面试问题。 这是我第一次使用coderpad.io(聪明的主意),也许是我第一次有人在编码时看着我的肩膀,而没有允许一两个StackOverflow。 面试官真的希望我用Java做到这一点,这让我感到不安,我已经使用Go编码了一段时间,并尝试使用Go进行编码。 我用注释将其伪编码出来,然后迅速间隔一下如何在Go中从字符串中获取该死的字符。 叹。

所以,我决定写这篇文章作为减轻自己对自己的失望的pen悔。

我现在正在为多种项目使用3种不同的语言:Go,Python和Swift(很好,Swift 3)。 老实说,我只是不保持这三个语法的全部一致性,我在编码时会进行很多模式匹配/复制/粘贴,并且很少再逐个关键字地将其键入。 我想,我上一次这样做是在1988-1992年的时间范围内使用Objective-C。 现在,当我使用这些微模式时,我的编码要好得多,并且在整个代码库中一切看起来都一样。

面试结束不到5分钟,我就可以使用Go版本了。 然后,今天早上,我以为,经过了这么多年,我又回过头去做同样的事情,被翻译成Java。 我猜想花了太长时间,但这让我想起了过去十年来我忘记了Java的东西,而我却忽略了它。 它也显示了一个有趣的案例,其中可以比较Go和Java,而Go表现得很好(IMHO)。 以及“ map:hashtable”一词; 它是“ Go:Java”,因此Go中的地图几乎是Java中的Hashtable。 恩比恩? 杰,好的。

测试数据:

  anagram(aab,aba)= true 
anagram(aab,cab)=否
anagram(aab,abdcefghijklmnopqrstuvwxyz)=否
//而且我知道,我知道(您是行家)符文**,
//但他说,不,只是一个简单的字符串。

首先,我决定将字谜决定放到一个函子中。

  // 走 
func anagram(x,y string)bool {
// Java
public boolean anagram(String x,String y){
//'x'是第一个字符串
//'y'是第二个字符串
//如果它们是彼此的字母,则返回true
//否则返回false。

我在两个特殊情况下进行了几次快速检查,以使例程短路:1)如果X等于Y(因此字符串相同),则返回true。 (在字谜的某些定义中,这可能并非严格正确 )。 2)如果两个字符串的长度不同,那么它们不是字谜,则返回false。

现在,在Go世界中,有两种方法可以声明map:hashtable ,其中键是字符串,值是整数。 但是基本思想是键/值存储库之一,将其作为键的值,然后当您通过键要求时将其取回。 (我记得Dictionary是Java的东西,不是吗?还是它一直是抽象类型?但是现在我知道Dictionary已过时了,请改用Map接口。)

  // 走 
dictx:= make(map [string] int)
// Java
Hashtable dictx = new Hashtable ();

这给我两个地方的map:hashtable。 这个想法很简单。 遍历每个字符串,构建map:hashtable,其中键是单个字母字符串,而值是在源字符串中看到该字母的次数。 进行两次,以每个源字符串的map:hashtable结尾。 然后遍历map:hashtables, 如果它们没有差异,则返回true 。 注意,我并不是说“如果map:hashtables相等…”。 这样可能会有龙。 无论如何,我首先想到“没有差异”。

我也在这里包括了一个快捷方式。 如果map:hashtable中的事物数量不相同(例如:2 vs 3),则它们不是字谜。 因此,“ aab”和“ abc”不是字谜。

然后,做简单的…

 对于字符串中的每个字符 
如果一个map:hashtable中的字符值与另一个不匹配,则返回false。

在Go中:anagram.go和Java:Anagram.java

有趣的来了。

我忘记了Java:

Java中的事情非常冗长。 分号。 哈希表的声明和分配给我留下了很多多余的印象。 如果我将变量声明为特定类型,则除了该类型之外,我将无法分配其他内容。 (Java曾经没有一个泛型的new()构造函数吗?也许我正在想象中。)我想象在某些地方这可能是正确的,但仍然如此。 分号。

哈希表周围的操作说明了为什么Go始终具有“空”值的概念是一个好方法。 在Java中,我必须检查哈希表是否具有条目,如果没有,请对其进行初始化。 好的,很多语言都是这样做的。 Go不会,因此您可以更快地在地图上移动。

Java for循环就像我记得C循环一样。 这样很好。 我忘记了for循环中的括号/主题,if语句等。

  // Java:通过字符串计算每个字符的数量 
for(int i = 0; i <x.length(); i ++){
字符串键= String.valueOf(x.charAt(i));
int值= 0;
如果(dictx.containsKey(key)){
值= dictx.get(key);
}其他{
dictx.put(key,0);
}
dictx.put(key,value + 1);
}
// **是的,我可以将键,值声明移出循环
//,这可能会导致某些速度差异

在Go中:

 对于我:= 0;  i <len(x); 我++ { 
dictx [string(x [i])] + = 1
}

最后,比较两个map:hashtables。 在Go中:

 如果len(dictx)!= len(dicty){ 
返回假
}
对于k,_:=范围dictx {
如果dictx [k]!= dicty [k] {
返回假
}
}

在Java中:

 如果(dictx.size()!= dicty.size()){ 
返回false;
}
Set 键= dictx.keySet();
for(字符串键:键){
如果(dicty.containsKey(key)){
如果(dictx.get(key)!= dicty.get(key)){
返回false;
}
}其他{
返回false;
}
}

然后,因为我真的很好奇,所以我使用“时间”在外壳中进行了非常不科学的计时。 Go当然拥有自己的地位。

我怀疑我可以重写Java循环,也许会花一些时间。 但是Java的一面是要记住我忘记的Java。 我不确定有人会说一个人比另一个人更好,但是它们显然是不同的。 Go可以在很多方面做得更好,但是总的来说,Go处于一个不错的位置。 My Java正在恢复的道路上,这很好,因为到目前为止,还没有人在附近雇用旧的Go黑客。

Java,请欢迎我回来? 我保证我不会抱怨;;;; 半;冒号;;; ;;; 我承诺。

Github Repo就是这个东西。 我还添加了相同的Swift版本。