天道酬勤,学无止境

如何在不调用java.lang.String的情况下检查clojure中字符串的相等性?(How to check the equality of strings in clojure without invoking java.lang.String?)

问题

clojure 中有什么方法可以检查字符串的相等性吗? 即我需要知道它们的内容是否相等,而不是位置。

谢谢。

回答1

Clojure 中的相等性( =函数)始终测试值,而不是身份,因此如果两个字符串具有相同的内容,则它们是=

对于大多数 Java 类型,包括 String,Clojure =分派到 Java .equals 。 String.equals 被定义为“代表相同的字符序列”。

如果要测试身份(这些指针是否指向内存中的同一位置?)使用identical? 功能。

回答2
(= "hello" (str "hel" "lo"))
; => true 

JVM 有一个字符串池,每个值最多保存一个条目,因此标识和值相等是相同的比较。 有多种使用StringBuilder.String. 这不是严格正确的,但因为 clojure 相等函数调用.equals ,如果身份不同,将执行值比较。

标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • compareTo()与equals()(compareTo() vs. equals())
    问题 在Java中测试String的相等性时,我一直使用equals()因为对我而言,这似乎是最自然的方法。 毕竟,它的名字已经说明了它打算做什么。 但是,我的一位同事最近告诉我,我被教导要使用compareTo() == 0而不是equals() 。 这感觉很不自然(因为compareTo()是为了提供顺序而不是为了相等而比较),甚至有些危险(因为compareTo() == 0不一定在所有情况下都意味着相等,即使我知道它对String '也是如此) s)给我。 他不知道为什么要教他在String使用compareTo()而不是equals() ,而且我也找不到任何原因。 这真的是个人喜好问题,还是使用这两种方法的真正原因? 回答1 不同之处在于, "foo".equals((String)null)返回false,而"foo".compareTo((String)null) == 0抛出NullPointerException。 因此,即使对于字符串,它们也不总是可互换的。 回答2 2个主要区别是: equals将任何对象作为参数,但是compareTo将仅接受字符串。 equals仅告诉您它们是否相等,但是compareTo提供有关字符串如何按字典顺序进行比较的信息。 我看了一看String类代码,compareTo和equals中的算法看起来基本相同。
  • 为什么Clojure对非法论点说“无匹配方法”?(Why does Clojure say “no matching method” for an illegal argument?)
    问题 正确使用Character / isWhitespace包括: (Character/isWhitespace \a) => false (Character/isWhitespace \ ) => true 但是,我的第一个尝试是这样做,我发现错误令人困惑。 (Character/isWhitespace "") => IllegalArgumentException No matching method found: isWhitespace => clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80) IllegalArgument部分有意义,但是为什么说“找不到匹配方法”? 显然,该功能确实存在。 澄清度 我问这个问题的原因是,我是Clojure的新手,并且认为我从根本上误解了某些东西。 当我输入(Character/isWhitespace \a) ,我想我要说的是:“我知道有一个Character命名空间,内有一个调用的函数isWhitespace ,我想调用该函数并传递\a ”。 在这种心智模型上,我的上述结果令人困惑,因为似乎Clojure在说:“每当您给我提供该函数不接受的参数类型时,我都会假装该函数不存在。” 例如,“您不允许混合砖块,因此,如果尝试尝试
  • 如何比较Java中的字符串?(How do I compare strings in Java?)
    问题 这个问题的答案是社区的努力。 编辑现有答案以改善此职位。 它目前不接受新的答案或互动。 到目前为止,我一直在程序中使用==运算符比较所有字符串。 但是,我遇到了一个错误,将其中一个更改为.equals() ,它修复了该错误。 ==不好吗? 什么时候应该使用它,不应该使用它? 有什么不同? 回答1 ==测试引用是否相等(它们是否是同一对象)。 .equals()测试值是否相等(在逻辑上是否相等)。 Objects.equals()在调用.equals()之前会检查是否为null ,因此您不必这样做(从JDK7开始可用,在Guava中也可用)。 因此,如果要测试两个字符串是否具有相同的值,则可能要使用Objects.equals() 。 // These two have the same value new String("test").equals("test") // --> true // ... but they are not the same object new String("test") == "test" // --> false // ... neither are these new String("test") == new String("test") // --> false // ... but these are because
  • 使用java.lang.String.intern()是一种好习惯吗?(Is it good practice to use java.lang.String.intern()?)
    问题 关于String.intern()的Javadoc并没有提供太多细节。 (简而言之:它返回字符串的规范表示形式,允许使用==来比较内部字符串) 我什么时候可以使用此函数来支持String.equals() ? 是否有Javadoc中未提及的副作用,即JIT编译器或多或少地进行了优化? 还有String.intern()其他用途吗? 回答1 我何时会使用此函数来支持String.equals() 当您需要速度时,因为可以按引用比较字符串(==比等于快) 是否有Javadoc中未提及的副作用? 主要缺点是您必须记住要确保实际上要对要比较的所有字符串执行intern()。 忘记intern()所有字符串很容易,然后您会得到令人困惑的不正确结果。 另外,为了大家的缘故,请确保非常清楚地证明您所依赖的是内部化的字符串。 如果决定内部化字符串的第二个缺点是intern()方法相对昂贵。 它必须管理唯一的字符串池,因此需要做很多工作(即使字符串已经内部化了)。 因此,在代码设计中要格外小心,例如,在输入时使用intern()所有合适的字符串,这样您就不必再为它烦恼了。 (来自JGuru) 第三个缺点(仅限Java 7或更低版​​本):实习字符串生活在PermGen空间中,该空间通常很小; 您可能会遇到带有大量可用堆空间的OutOfMemoryError。 (摘自Michael
  • Clojure中的'()和(list)有什么区别?(What's the difference between '() and (list) in Clojure?)
    问题 清单上的API备忘单部分似乎表明'()是一个列表构造函数,就像(list) ,但是我发现实际上它们并不完全相同。 例如,给定: (def foo "a") (def bar "b") (def zip "c") 以下语句: (apply str '(foo bar zip)) 产生输出“ foobarzip”,这是我所不希望的。 但据称是等效的: (apply str (list foo bar zip)) 如我所料,会产生“ abc”。 这里发生了什么? 如果Clojure中的列表有“简写形式”(例如{}表示地图, [] vector []表示矢量),那是什么? 回答1 在lisps中, ' (如quote )引用其参数,即几乎完全按照其s-exp形式编写它们,包括不评估其中的任何内容。 换句话说, '(foo bar zip)创建一个包含符号foo , bar , zip ; while (list foo bar zip)创建一个包含foo , bar和zip值的列表。 在第一种情况下, str会将符号本身转换为字符串,然后将它们串联起来。 作为说明: => (def foo "a") => (type (first '(foo))) clojure.lang.Symbol => (type (first (list foo))) java.lang.String
  • 字符串对象和字符串文字之间的区别(Difference between string object and string literal [duplicate])
    问题 这个问题已经在这里有了答案: “文本”和新字符串(“文本”)之间有什么区别? (12个答案) 7年前关闭。 之间有什么区别 String str = new String("abc"); 和 String str = "abc"; 回答1 当您使用字符串文字时,可以将字符串插入,但是当您使用new String("...")您将获得一个新的字符串对象。 在此示例中,两个字符串文字均引用相同的对象: String a = "abc"; String b = "abc"; System.out.println(a == b); // true 在这里,创建了2个不同的对象,它们具有不同的引用: String c = new String("abc"); String d = new String("abc"); System.out.println(c == d); // false 通常,应尽可能使用字符串文字表示法。 它更易于阅读,并且为编译器提供了优化代码的机会。 回答2 字符串文字是Java语言的概念。 这是一个字符串文字: "a String literal" String对象是java.lang.String类的单个实例。 String s1 = "abcde"; String s2 = new String("abcde"); String s3 = "abcde"
  • 在不重新启动Web服务器的情况下进行Compojure开发(Compojure development without web server restarts)
    问题 我以前在Clojure中编写了一个小型的Swing应用程序,现在我想创建一个Ajax风格的Web应用程序。 Compojure看起来现在是最好的选择,所以这就是我要尝试的方法。 我希望有一个很小的编辑/尝试反馈循环,所以我不希望在每次进行小的更改后都不要重新启动Web服务器。 做到这一点的最佳方法是什么? 默认情况下,我的Compojure设置(带有ant deps的标准内容/带有Jetty的ant)似乎不会重新加载我所做的任何更改。 我将不得不使用run-server重新启动以查看更改。 由于Java的继承性以及系统的启动方式等原因,这可能是完全正常的,并且应该是从命令行启动系统时应采用的方式。 仍然必须有一种在服务器运行时动态重新加载内容的方法。 我应该使用REPL的Compojure来实现我的目标吗? 如果可以的话,我该如何在这里重新加载我的东西? 回答1 这是一个很老的问题,最近进行了一些更改,使这一过程变得更加容易。 您需要做两件事: 控制权应返回到REPL,以便您可以继续与服务器进行交互。 这可以通过添加{:join? 启动Jetty服务器时的选项。 您想在文件更改时自动选择某些命名空间中的更改。 可以使用Ring的“包装重新加载”中间件来完成。 一个玩具应用程序将如下所示: (ns demo.core (:use webui.nav [clojure.java
  • 编译Java类时禁用编译时依赖性检查(Disabling compile-time dependency checking when compiling Java classes)
    问题 考虑以下两个Java类: a.) class Test { void foo(Object foobar) { } } b.) class Test { void foo(pkg.not.in.classpath.FooBar foobar) { } } 此外,假定在类路径中找不到pkg.not.in.classpath.FooBar 。 第一类将使用标准javac进行编译。 但是,第二个类将无法编译,并且javac会给您错误消息"package pkg.not.in.classpath does not exist" 。 该错误消息在一般情况下是很好的,因为检查您的依赖项可使编译器告诉您某些方法参数是否错误,等等。 虽然很好并且很有帮助,但是在上面的示例中,并非严格要求在编译时检查依赖项是AFAIK来生成Java类文件。 您能否举任何在不执行编译时相关性检查的情况下无法生成有效Java类文件的示例? 您是否知道有任何方法可以指示javac或任何其他Java编译器跳过编译时间依赖关系检查? 请确保您的答案解决了两个问题。 回答1 您能否举任何在不执行编译时相关性检查的情况下无法生成有效Java类文件的示例? 考虑以下代码: public class GotDeps { public static void main(String[] args) { int i = 1
  • 如何在Clojure中将字符转换为int?(How to cast a character to int in Clojure?)
    问题 如何在Clojure中将字符转换为int? 我正在尝试用clojure写一个烂13,所以我需要一些东西来将char转换为int。 我找到了一个叫做(int)的东西,所以我把: (int a) 获取:CompilerException java.lang.RuntimeException:无法解析符号:a在这种情况下,编译:(NO_SOURCE_PATH:13:1) 然后我把: (int 'a) 获取:ClassCastException clojure.lang.Symbol无法转换为`java.lang.Character clojure.lang.RT.intCast(RT.java:1087) 然后: (rot13 ''a') 获取:ClassCastException clojure.lang.PersistentList无法转换为java.lang.Character clojure.lang.RT.intCast(RT.java:1087) 和: (rot13 "a") 得到: ClassCastException java.lang.String cannot be cast to java.lang.Character clojure.lang.RT.intCast (RT.java:1087) 那么正确的方法是什么呢? 顺便说一句
  • “文本”和新字符串(“文本”)之间有什么区别?(What is the difference between “text” and new String(“text”)?)
    问题 以下两个语句之间有什么区别? String s = "text"; String s = new String("text"); 回答1 new String("text"); 显式创建String对象的新的且具有参照性的不同实例; String s = "text"; 如果有一个实例,可以从字符串常量池中重用一个实例。 您很少会想使用new String(anotherString)构造函数。 从API: String(String original):初始化一个新创建的String对象,以便它表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本。 除非需要显式的原始副本,否则不需要使用此构造函数,因为字符串是不可变的。 相关问题 Java字符串:“字符串s =新字符串(“傻”));” 字符串是Java中的对象,那么为什么不使用'new'来创建它们呢? 参照区别是什么意思 检查以下代码段: String s1 = "foobar"; String s2 = "foobar"; System.out.println(s1 == s2); // true s2 = new String("foobar"); System.out.println(s1 == s2); // false System.out.println(s1.equals(s2)); //
  • 如何在不获取“ SomeType @ 2f92e0f4”的情况下打印Java对象?(How do I print my Java object without getting “SomeType@2f92e0f4”?)
    问题 我有一个定义如下的类: public class Person { private String name; // constructor and getter/setter omitted } 我试图打印我的班级的实例: System.out.println(myPerson); 但我得到以下输出: com.foo.Person@2f92e0f4 。 当我尝试打印一个Person对象数组时,发生了类似的事情: Person[] people = //... System.out.println(people); 我得到了输出: [Lcom.foo.Person;@28a418fc 此输出是什么意思? 如何更改此输出,使其包含我的人的名字? 以及如何打印我的对象的集合? 注意:这是关于此主题的规范问答。 回答1 背景 所有Java对象都有一个toString()方法,当您尝试打印该对象时会调用该方法。 System.out.println(myObject); // invokes myObject.toString() 此方法在Object类(所有Java对象的超类)中定义。 Object.toString()方法返回一个看起来很难看的字符串,该字符串由类的名称, @符号和对象的哈希码(十六进制)组成。 此代码如下所示: // Code of Object.toString
  • 什么是反射,为什么有用?(What is reflection and why is it useful?)
    问题 什么是反射,为什么有用? 我对Java特别感兴趣,但是我认为所有语言的原理都是相同的。 回答1 名称反射用于描述能够检查同一系统(或本身)中的其他代码的代码。 例如,假设您在Java中有一个未知类型的对象,并且您想在该对象上调用“ doSomething”方法(如果存在)。 除非对象符合已知接口,否则Java的静态类型化系统并不是真正为支持此类型而设计的,但是使用反射,您的代码可以查看该对象并确定其是否具有名为“ doSomething”的方法,然后在需要时调用该方法。想要。 因此,给您一个用Java编写的代码示例(假设有问题的对象是foo): Method method = foo.getClass().getMethod("doSomething", null); method.invoke(foo, null); Java中一种非常常见的用例是带注释的用法。 例如,JUnit 4将使用反射在类中查找使用@Test批注标记的方法,然后在运行单元测试时调用它们。 有一些不错的反思示例,可帮助您入门:http://docs.oracle.com/javase/tutorial/reflect/index.html 最后,是的,在其他支持反射的静态类型语言(如C#)中,这些概念非常相似。 在动态类型的语言中,上述用例不是必需的(因为编译器将允许在任何对象上调用任何方法
  • 带类的Clojure案例陈述(Clojure case statement with classes)
    问题 我想打开给定对象的类以对其进行编码。 (defn encoded-msg-for [msg] (case (class msg) java.lang.Double (encode-double msg) java.lang.String (encode-str msg) java.lang.Long (encode-int msg) java.lang.Boolean (encode-bool msg) clojure.lang.PersistentArrayMap (encode-hash msg) clojure.lang.PersistentVector (encode-vec msg) nil "~" ) ) 当我调用(encoded-msg-for {}) ,它No matching clause: class clojure.lang.PersistentArrayMap返回No matching clause: class clojure.lang.PersistentArrayMap 奇怪的是,将案例放入哈希图中(类作为键,字符串作为值)非常好。 另外, (= (class {}) clojure.lang.PersistentArrayMap)为true。 这里发生了什么比较,如何切换对象本身的类或(更好)其层次结构中的某个对象? 回答1
  • 什么是静态工厂方法?(What are static factory methods?)
    问题 什么是“静态工厂”方法? 回答1 我们避免直接访问数据库连接,因为它们是资源密集型的。 因此,我们使用静态工厂方法getDbConnection来创建连接(如果我们低于限制)。 否则,它将尝试提供“备用”连接,如果不存在则失败,并显示异常。 public class DbConnection{ private static final int MAX_CONNS = 100; private static int totalConnections = 0; private static Set<DbConnection> availableConnections = new HashSet<DbConnection>(); private DbConnection(){ // ... totalConnections++; } public static DbConnection getDbConnection(){ if(totalConnections < MAX_CONNS){ return new DbConnection(); }else if(availableConnections.size() > 0){ DbConnection dbc = availableConnections.iterator().next()
  • java基础知识点整理
    1.&和&&的区别? &:逻辑与(and),运算符两边的表达式均为true时,整个结果才为true。 &&:短路与,如果第一个表达式为false时,第二个表达式就不会计算了。 2.在java中如何跳出当前的多重循环? 在循环语句外前面定义一个标号,然后在里层循环体的代码中使用带有标号的break语句,即可跳出循环。 比如: ok: for (int i = 0; i < 10; i++) { { for (int j = 0; j < 10; j++) { break ok; } } } 3.最有效率的方法算出2X8等于几? 使用位运算,效率最高:2<<3,表示2向右移动了3位,就相当于2乘以2的3次方,结果:16。 4.”==”和equals方法究竟有什么区别? == 表示两个变量的值是否相等,比较两个基本数据类型的数据或者引用变量,用==。 equals:用于比较两个独立对象的内容是否相同。字符串的比较也用equals。 5. Int和integer的区别? Int是Java的8中基本数据类型之一,integer是int的封装类。Int类型的默认值为0,integer默认值为null,所以区别在于,integer能区分出null值和0的区别。 6.三个与取整有关的方法: Math.ceil():表示向上取整;Math.ceil(11.3)=12;Math.ceil(-11.3)
  • Java:如何检查对象是否为空?(Java: How to check if object is null?)
    问题 我正在创建一个从网络检索图像的应用程序。 如果图像无法检索,则应使用另一个本地图像。 在尝试执行以下几行时: Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath()); if (drawable.equals(null)) { drawable = getRandomDrawable(); } 如果 drawable 为 null,则 if(drawable.equals(null)) 行会引发异常。 有谁知道应该如何检查 drawable 的值,以便在它为 null 的情况下不抛出异常并检索本地图像(执行 drawable = getRandomDrawable())? 回答1 编辑的 Java 8 解决方案: final Drawable drawable = Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath())) .orElseGet(() -> getRandomDrawable()); 在这种情况下,您可以声明drawable final 。 正如 Chasmo 所指出的,Android 目前不支持 Java 8。 因此,此解决方案仅适用于其他情况。 回答2 Drawable
  • JVM内存模型和类加载运行机制
    目录一、JVM内存模型1、堆2、方法区3、虚拟机栈4、本地方法栈5、程序计数器二、类加载机制三、类编译和Class 文件结构1、魔数与Class文件信息2、常量池3、类索引、父类索引与接口索引4、字段表5、方法表6、属性表四、类加载1、类初始化的时机2、加载3、验证4、准备5、解析6、初始化7、即时编译五、类加载器1、类加载器子系统2、双亲委派模型3、线程上下文类加载器六、对象及其生命周期1、实例化对象2、对象的内存布局3、对象访问定位4、垃圾收集参考一、JVM内存模型运行一个 Java 应用程序,必须要先安装 JDK 或者 JRE 包。因为 Java 应用在编译后会变成字节码,通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分。JVM 不仅承担了 Java 字节码的分析和执行,同时也内置了自动内存分配管理机制。这个机制可以大大降低手动分配回收机制可能带来的内存泄露和内存溢出风险,使 Java 开发人员不需要关注每个对象的内存分配以及回收,从而更专注于业务本身。在 Java 中,JVM 内存模型主要分为堆、方法区、程序计数器、虚拟机栈和本地方法栈。其中,堆和方法区被所有线程共享,虚拟机栈、本地方法栈、程序计数器是线程私有的。1、堆堆是 JVM 内存中最大的一块内存空间,该内存被所有线程共享,几乎所有对象和数组都被分配到了堆内存中。堆被划分为新生代和老年代
  • 字符串文字池是对字符串对象的引用集合,还是对象的集合(Is String Literal Pool a collection of references to the String Object, Or a collection of Objects)
    问题 阅读了SCJP Tip Line的作者Corey McGlone在javaranch网站上的文章后,我都感到困惑。 从字面上看是Strings,由Kathy Sierra(javaranch的联合创始人)和Bert Bates共同编写的《 SCJP Java 6程序员指南》。 我将尝试引用Corey先生和Kathy Sierra女士对String Literal Pool的引用。 1.根据科里·麦格隆先生的说法: 字符串文字池是指向字符串对象的引用的集合。 String s = "Hello"; (假定堆上没有名为“ Hello”的对象),将在堆上创建一个字符串对象"Hello" ,并将对该对象的引用放入字符串文字池(常量表)中String a = new String("Bye"); (假设堆上没有名为“ Bye”的对象, new操作符将迫使JVM在堆上创建一个对象。 现在,在本文中对用于创建String及其引用的"new"运算符的解释有些混乱,因此,我将下面的文章本身的代码和解释放在此处。 public class ImmutableStrings { public static void main(String[] args) { String one = "someString"; String two = new String("someString")
  • 什么是NullPointerException,我该如何解决?(What is a NullPointerException, and how do I fix it?)
    问题 这个问题的答案是社区的努力。 编辑现有答案以改善此职位。 它目前不接受新的答案或互动。 什么是Null Pointer异常( java.lang.NullPointerException ),是什么原因导致的? 可以使用哪些方法/工具确定原因,以阻止异常导致程序过早终止? 回答1 声明引用变量(即对象)时,实际上是在创建指向对象的指针。 考虑以下代码,您在其中声明基本类型为int的变量: int x; x = 10; 在此示例中,变量x是一个int ,Java会为您将其初始化为0 。 当您在第二行上分配值10时,您的值10被写入x所指的存储位置。 但是,当您尝试声明引用类型时,会发生一些不同的事情。 采取以下代码: Integer num; num = new Integer(10); 第一行声明了一个名为num的变量,但实际上尚未包含原始值。 相反,它包含一个指针(因为类型是Integer ,它是引用类型)。 由于您尚未说出要指向的内容,因此Java将其设置为null ,这意味着“我什么都没有指向”。 在第二行中, new关键字用于实例化(或创建) Integer类型的对象,并且将指针变量num分配给该Integer对象。 NullPointerException (NPE)在声明变量但未创建对象并将其分配给该变量,然后再尝试使用该变量的内容(称为dereferencing
  • 如何使用“”初始化字符串?(How can a string be initialized using “ ”?)
    问题 如果String和其他字符串一样是一个类,如何使用双引号将其初始化? 回答1 Java字符串很特殊 Java的设计者决定保留面向对象语言中的原始类型,而不是将所有内容都变成对象,以提高语言的性能。 原语存储在调用堆栈中,这需要较少的存储空间并且更便宜。 另一方面,对象存储在程序堆中,这需要复杂的内存管理和更多的存储空间。 出于性能原因,Java的String设计为介于基本体和类之间。 例如 String s1 = "Hello"; // String literal String s2 = "Hello"; // String literal String s3 = s1; // same reference String s4 = new String("Hello"); // String object String s5 = new String("Hello"); // String object 注意:字符串文字存储在公共池中。 这有助于共享具有相同内容的字符串的存储,以节省存储空间。 通过new运算符分配的String对象存储在heap ,并且相同内容不共享存储。 回答2 Java将String视为特殊类,您可以通过两种方式进行初始化 直接分配文字String a = "adsasdf"; 和其他使用new关键字的对象一样String a = new String