有很多示例显示了如何像这样使用StandardTokenizer:

TokenStream tokenStream = new StandardTokenizer(
            Version.LUCENE_36, new StringReader(input));

但是在较新的Lucene版本中,此构造函数不可用。新的构造函数如下所示:
StandardTokenizer(AttributeFactory factory)

这个AttributeFactory的作用是什么,如何在新版本的Lucene中标记一个String?

最佳答案

AttributeFactory创建AttributeImpl,它是Attribute的源。属性控制TokenStream的行为,这是用于读取/跟踪StandardTokenizer数据流的基础机制。

AttributeFactory而言,从4.x到5.x的变化很小-在两种版本中,如果您愿意,都可以使用StandardTokenizer创建一个AttributeFactory,或者如果您不指定,则AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY最终会结束正在使用。

最大的区别是您还可以为构造器的一部分传递输入流的Reader。这意味着在4.x中,您将必须为要处理的每个输入流创建一个新的StreamTokenizer,这又必须从AttributeFactory重新初始化属性。

我不是Lucene开发人员,但我的猜测是这只是一个重组,以鼓励在读取多个流时重用属性。如果您看一下TokenStream的内部结构和默认的AttributesFactory实现,那么在创建和设置属性时会有很多反射(reflection)。如果我不得不猜测的话,只是删除了采用阅读器的StreamTokenizer构造函数,以鼓励 token 程序及其属性的重用,因为这些属性的初始化相对昂贵。

编辑

添加一个逾期未交的示例-抱歉,您不能这样做:

// Define your attribute factory (or use the default) - same between 4.x and 5.x
AttributeFactory factory = AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY;

// Create the tokenizer and prepare it for reading
//  Lucene 4.x
StandardTokenizer tokenizer =
        new StandardTokenizer(factory, new StringReader("Tokenize me!"));
tokenizer.reset();
//  Lucene 5.x
StandardTokenizer tokenizer = new StandardTokenizer(factory);
tokenizer.setReader(new StringReader("Tokenizer me!"));
tokenizer.reset();

// Then process tokens - same between 4.x and 5.x
// NOTE: Here I'm adding a single expected attribute to handle string tokens,
//  but you would probably want to do something more meaningful/elegant
CharTermAttribute attr = tokenizer.addAttribute(CharTermAttribute.class);
while(tokenizer.incrementToken()) {
    // Grab the term
    String term = attr.toString();

    // Do something crazy...
}

08-25 14:41