访问匿名类之外的变量

时间:2018-12-10 08:54:19

标签: java ibm-watson speech-to-text anonymous-class

我目前正在使用IBM Watson java SDK中包含的IBM语音到文本服务。我正在尝试将笔录字符串设置为等于结果笔录。但是,当我运行此代码时,不会打印该值。我不确定为什么会这样,或者如何解决问题。任何帮助,将不胜感激。我尝试在main方法外部使用带有静态变量的外部setter,但未成功。

final String[] transcript = {""};
    service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
        @Override
        public void onTranscription(SpeechRecognitionResults speechResults) {
            for(int i = 0; i < speechResults.getResults().size(); i++){
                transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
            }
        }
    });
    System.out.println(transcript[0]);

2 个答案:

答案 0 :(得分:1)

问题在于recognizeUsingWebSocket是一个异步调用。因此,在您进行System.out.println(transcript[0]时,您对IBM Watson服务的呼叫很可能尚未完成。

当触发回调方法onTranscription时,您将知道异步操作已完成。因此,在该方法内部以及在for循环之后,可以确保transcript数组中已经有一些值。在那里,您可以随心所欲地处理结果。

如果您想在回调之外使用脚本值,最简单的解决方案是在您的类中定义一个新方法,并在onTranscript回调的末尾调用它。

...
public void onTranscriptReceived(String[] transcript) {
     // Do whatever you want
}
...

final String[] transcript = {""};
service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
    @Override
    public void onTranscription(SpeechRecognitionResults speechResults) {
        for(int i = 0; i < speechResults.getResults().size(); i++){
            transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
        }
        onTranscriptReceived(transcript);
    }
});

还有许多其他解决方案可用于处理异步调用。就个人而言,我喜欢ReactiveX库,在您的情况下,我喜欢RxJava specifically。学习可能需要一些时间,但是绝对值得。

答案 1 :(得分:0)

您可以将数组脚本包装在具有自己的处理程序或使用者(可以处理异步请求的方法)的类中。

像这样:

import java.util.function.Consumer;

public class ArrayWrapper {

    private Consumer consumer;

    private Object [] array;

    public ArrayWrapper(int size) {
        this.array = new Object [size];
    }

    public void addConsumer(Consumer consumer) {
        this.consumer = consumer;
    }

    public void add(Object o, int index) {
        array[index] = o;
        consumer.accept(o);
    }

    public Object [] get() {
        return array;
    }
}

然后,您可以在Consumer中实现逻辑:

ArrayWrapper transcript = new ArrayWrapper(1);
transcript.addConsumer(new Consumer() {
    @Override
    public void accept(Object o) {
        // perform your operations 
        System.out.println(o);
    }
});

service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
    @Override
    public void onTranscription(SpeechRecognitionResults speechResults) {
        for(int i = 0; i < speechResults.getResults().size(); i++){
            String newTranscript = transcript.get()[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
            transcript.add(newTranscript, 0);
        }
    }
});

这只是一个例子,但是您的想法是您要么必须在回调内部使用一个函数,要么要告诉您何时在回调内部完成循环或类似操作。

编辑:

或者您可以通过更简单的方式(无需任何其他类)来做到这一点:

    final String[] transcript = {""};
    Consumer<String> consumer = new Consumer<String>() {
        @Override
        public void accept(String s) {
            //your operations
            System.out.println(s);
        }
    };
    service.recognizeUsingWebSocket(options, new BaseRecognizeCallback() {
        @Override
        public void onTranscription(SpeechRecognitionResults speechResults) {
            for(int i = 0; i < speechResults.getResults().size(); i++){
                transcript[0] = transcript[0] + speechResults.getResults().get(i).getAlternatives().get(0).getTranscript() + "\n";
                consumer.accept(transcript[0]);
            }
        }
    });
}