当前位置: 首页 > 知识库问答 >
问题:

equalsIgnoreCase()相对于toUpperCase()的效率。等于和toLowerCase()。等于

严安志
2023-03-14

标题说明了一切。我的问题是关于不同的字符串等价方法的效率。我经常使用<代码>。equalsIgnoreCase(String str),因为我对它很有兴趣。但我开始怀疑这是否是寻找字符串之间等价性的最有效方法。在我看来,。equalsIgnoreCase(String str)正在调用一种大小写转换方法toupercasetoLowerCase,然后在其定义中调用equals,但我可能错了。那么,以下哪种方法在以下情况或任何情况下更有效?

int count = 0;//checks for face cards at indexes listed in selectedCards
              // Selected cards is Integer ArrayList

    for(; (count < selectedCards.size() && count < 3); count++)
    {
        if(cardAt(selectedCards.get(count)).rank().equalsIgnoreCase("Queen"))
            count++;
        else if(cardAt(selectedCards.get(count)).rank().equalsIgnoreCase("King"))
            count++;
        if(cardAt(selectedCards.get(count)).rank().equalsIgnoreCase("Jack"))
            count++;
    }

    if(count == 3)
        return true;
    return false;

共有3个答案

花阳秋
2023-03-14

您可以自己简单地检查代码(它包含在SDK中)。

这个equalsIgnoreCase比toUperCase()快。equals()在java 8中,代码为:

   while (len-- > 0) {
        char c1 = ta[to++];
        char c2 = pa[po++];
        if (c1 == c2) {
            continue;
        }
        if (ignoreCase) {
            // If characters don't match but case may be ignored,
            // try converting both characters to uppercase.
            // If the results match, then the comparison scan should
            // continue.
            char u1 = Character.toUpperCase(c1);
            char u2 = Character.toUpperCase(c2);
            if (u1 == u2) {
                continue;
            }
            // Unfortunately, conversion to uppercase does not work properly
            // for the Georgian alphabet, which has strange rules about case
            // conversion.  So we need to make one last check before
            // exiting.
            if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
                continue;
            }
        }
        return false;
    }
    return true;

因此,如果比较的字符串实际上不同,它将比第一次调用toUpderCase然后等于更快,因为toUperCase将修改所有字符。此外,toUperCase中涉及的逻辑似乎比比较循环中更复杂,它在最后创建了一个新的String对象。

但你需要进行大量的比较操作才能真正看到任何差异。

万俟经纶
2023-03-14

令人惊讶的是,由于一些奇怪的Unicode原因,这些方法并不等价:

  • toUpperCase("ß")返回"SS",即两个字母,而equalsIgnoreCase按字符工作
  • 对于某些字符,toUpperCasetoLowerCase都不够,您必须同时执行

关于效率,我敢打赌,equalsIgnoreCase要快得多,因为它不会复制任何数据。它还从长度比较开始。

还要注意的是,toUpperCase和toLowerCase敏感,而equalsIgnoreCase不敏感。IIRC如果使用外来语言环境,性能会降低。

最好、最简单的优化方法是事先对套管进行规范化。没有理由在您的数据中有“Queen”、“Queen”和“Queen”——请尽快清理输入。

您还可以使用枚举来表示排名。

恐怕,你的循环坏了。在任何一张JQK之后,你跳过一张牌,这是有意的吗???

执行以下操作

  • 使用foreach循环保持其清洁

不使用enums和早期规范化的代码如下所示:

int count = 0;
// Whatever Position is
for (Position p : selectedCards) {
    String rank = cardAt(p).rank();
    if (rank.equalsIgnoreCase("Jack")
            || rank.equalsIgnoreCase("Queen")
            || rank.equalsIgnoreCase("King")) {
        ++count;
    if (count > 3) { // Tiny and probably useless optimization.
        return false;
    }
}
return count == 3;
索嘉石
2023-03-14

JMH使微基准测试变得容易:

更新:将输入字符串设置为参数以处理来自JMH上帝Alexey ShiPilev的评论。我将目标字符串保留为常量,因为OP的用例是将输入字符串与常量进行比较。

@State(Benchmark)
public class StrComp {

    @Param({"Queen", "queen", "King"})
    public String input;

    @Benchmark
    public boolean eqIgnoreCase() {
        return input.equalsIgnoreCase("queen");
    }

    @Benchmark
    public boolean eqToLower() {
        return input.toLowerCase().equals("queen");
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(".*StrComp.*")
                .mode(Mode.AverageTime)
                .timeUnit(TimeUnit.NANOSECONDS)
                .forks(5)
                .warmupIterations(10)
                .measurementIterations(10)
                .build();

        new Runner(opt).run();
    }
}

和输出:

Benchmark             Mode  Cnt   Score   Error  Units
StrComp.eqIgnoreCase  avgt   50  18.581 ± 0.051  ns/op
StrComp.eqToLower     avgt   50  54.796 ± 0.173  ns/op

使用参数更新输出:

Benchmark             (input)  Mode  Cnt   Score   Error  Units
StrComp.eqIgnoreCase    Queen  avgt   50  17.947 ± 0.205  ns/op
StrComp.eqIgnoreCase    queen  avgt   50  15.553 ± 0.159  ns/op
StrComp.eqIgnoreCase     King  avgt   50   2.968 ± 0.037  ns/op
StrComp.eqToLower       Queen  avgt   50  56.499 ± 0.180  ns/op
StrComp.eqToLower       queen  avgt   50  22.023 ± 0.040  ns/op
StrComp.eqToLower        King  avgt   50  49.174 ± 0.145  ns/op

因此,eqIgnoreCase速度更快,但除非每秒进行一百万次比较,否则不会注意到任何差异。

您可以四处玩玩,看看如果第一个字符串已经是小写或字符串的长度不同等,差异会如何影响。

无论如何,如果你想让你的代码更“高效”,更清晰,更安全,更不容易出现bug,那么就不要使用字符串。使用枚举。

卡片组非常适合使用enum实现,它经常用于说明enum的概念:http://docs.oracle.com/javase/8/docs/technotes/guides/language/enums.html#Card

 类似资料:
  • 问题内容: 我正在Mac上使用Eclipse IDE(版本:3.4.2),但遇到了以下问题。 使用equal()或equalsIgnoreCase()方法在字符串之间进行比较时,即使字符串相等,我也会收到false。例如,即使values [0] =“ debug_mode”,以下代码也将以下条件视为false: 这是以下循环的一部分: 我尝试使用并获得了相同的结果。有人知道为什么吗? 问题答案:

  • 问题内容: 我正在从xml配置转移到注释。我想转换一个会话范围的bean是 可以通过注释完成此操作吗?如果没有,我该怎么做才能使该声明继续工作? 问题答案: 在spring上下文xml中,执行以下操作: 请注意,尽管如此,你将需要为该包中的所有类编写接口。

  • 问题内容: 我在Android应用程序中向用户显示图像。 我希望能够告诉他们“触摸”图像的位置。 我可以通过实现OnTouchListener轻松获取屏幕坐标 但是,这些是绝对坐标。我真正需要的是一个将其转换为相对于View的坐标的函数。 我做了一些挖掘工作,但是除了尝试自己实现ScreenToClient方法之外,我似乎什么也没做。 有谁知道一个好的解决方案,还是我只需要自己动手? 似乎可以使用

  • 问题内容: 据我所知,Java没有C#之类的东西。是否有其他Java库提供类似功能?( 反射反射 )有什么区别? 问题答案: 除了达林的出色答案(+1)外,ASM也值得一试。

  • 问题内容: 我试图找到与generate_series()(PostgreSQL语法)相当的snowflake。 问题答案: 这就是我能够在Snowflake中生成一系列日期的方式。我将行数设置为1095,以获得3年的日期,您当然可以将其更改为适合您的用例的日期 最初在这里找到 编辑:此解决方案是不正确的。不能保证序列无间隙。请遵循其他答案,而不是这个。感谢@Marcin Zukowski指出这一

  • 问题内容: 该表示法是: 实际上不哈希对象;它实际上只是转换为字符串(通过它是一个对象,还是其他各种原始类型的内置转换),然后在“ ”中查找该字符串,而不对其进行哈希处理。也不会检查对象是否相等-如果两个不同的对象具有相同的字符串转换,则它们将彼此覆盖。 鉴于此-在JavaScript中是否有任何有效的hashmap实现?(例如,第二个Google结果产生的实现对任何操作都是O(n)。其他各种结果