首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java中的名称过滤

Java中的名称过滤
EN

Code Review用户
提问于 2014-12-31 03:48:59
回答 2查看 197关注 0票数 6

我有一个搜索框,用来搜索名单中的人。以下是每次查询更改时运行的代码。我找不到任何开源的,所以我想确保这看起来很好和有效率。

看起来怎么样?

代码语言:javascript
复制
private final List<String> mTotalNames = ............ // some ArrayList<String> with all the names
private final List<String> mAvailableNames = new ArrayList<String>(mTotalNames);

private void doOnQueryTextChange(final String s) {
    mAvailableNames.clear();
    if (s.length() <= 0) {
        mAvailableNames.addAll(mTotalNames);
    } else {
        final String query = s.toLowerCase();
        for (String name : mTotalNames) {
            name = name.toLowerCase();
            final List<String> partNameList
                    = new LinkedList<String>(Arrays.asList(name.split("\\s+")));
            if (helper0(query, partNameList)) {
                mAvailableNames.add(user);
            }
        }
    }
    // yeah, out mAvailableNames is all updated
}

private static boolean helper0(final String query, final List<String> partNameList) {
    for (String partQuery : query.split("\\s+")) {
        if (!helper1(partQuery, partNameList)) {
            return false;
        }
    }
    return true;
}

private static boolean helper1(final String partQuery, final List<String> partNameList) {
    if (partQuery.trim().length() <= 0) return true;
    final Iterator<String> iterator = partNameList.iterator();
    while (iterator.hasNext()) {
        final String partName = iterator.next();
        if (partName.startsWith(partQuery)
                || partName.trim().length() <= 0) {
            iterator.remove();
            return true;
        }
    }
    return false;
}
EN

回答 2

Code Review用户

发布于 2014-12-31 14:47:07

注意:在这个问题中,这个答案中提出的概念是在下面的“备用”实现中实现的:未定义

有趣的问题。您的代码很难阅读,不是因为它是非结构化的,或者是混乱的,而是因为助手函数的名称很难理解.他们干些什么?

所以,从好的方面来说,你的“视觉”风格是一致的,整洁的。你所有的线条都有很好的缩进和支撑,等等。嗯,除了这一行:

代码语言:javascript
复制
if (partQuery.trim().length() <= 0) return true;

命名

第一个问题是命名..。四件事:

  1. helper0helper1。不管名字是什么,都不要帮忙。
  2. 这不是什么大不了的事,它可能是一个“本地规则”,但在Java中使用“前缀”作为变量名是非常规的。m是什么意思?mTotalNames应该是totalNames。您正在使用某种类型的“匈牙利”符号,这在Java中不是很好的实践。
  3. “部分”在很多地方超载。partQuerypartNamepartNameList,很难记住哪些变量是哪个变量。
  4. iterator是个可怕的名字。我们知道它是一个迭代器,但是它迭代什么呢?

算法

在这种情况下,正确的数据结构将有很大帮助。你在做和重复太多的工作。考虑到这一点:

  1. 您经常将名称转换为小写。
  2. 你把名字分开..。经常这样。
  3. 你有前缀..。经常这样。

您需要的是一个更好的算法,而正确的一个是构建三轮车

trie将由名称中的字符索引。这将允许您以非常快速的方式搜索名称,而不会重复执行任何开销处理。构建trie一次,然后在键入时反复使用它来筛选名称。

Bug

您的代码将无法正确处理特定名称/查询的子集。

想想“安迪·安德森”这个名字,还有搜索“和安迪”.这将不匹配,因为搜索查询词' and‘将首先与'Andy’匹配,然后剩下搜索词'Andy',这将与'Anderson‘这个词不匹配。

您需要按长度递减顺序对搜索项进行排序,并且始终首先使用最长的查询项进行搜索。

跟踪

这个话题引起了我的兴趣,我可以自己来实现我推荐的解决方案.再过一天左右。

票数 5
EN

Code Review用户

发布于 2014-12-31 05:30:18

首先有几个:

  • mFriendsList?应该是mTotalNames
  • 这可以初始化为new ArrayList<>(mTotalNames.size());,因为您已经在您的函数中处理这个问题了。私有List mAvailableNames =新ArrayList(mTotalNames);
  • 您的助手函数最后得到的结果似乎是错误的名称列表:{"Nightly“、"You Next”、“The space”};查询字符串:y nex --您的结果:您预期的:全名应该以给定的字符串开始,而不考虑空格,或者全名应该包含字符串,而不管名称是什么。
  • 命名:请添加一些价值,无论是在名称或评论,以前的首选,使其赋予功能的个性。更正:helper0, helper1.
  • 使用StringUtils.isBlank()代替此检查空空查询字符串: if (s.length() <= 0)
  • 集合的集体过度使用:新的LinkedList(Arrays.asList(name.split("\s+")));链接
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/75311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档