我读了一个数字文件,我想点击一个按钮。单击该按钮时,数字将输出平均值而不是仅输出数字,而不会中断传入的数据流。
我想要实时操纵流。这就是我想知道的。
如何做到这一点?
泰
答案 0 :(得分:1)
这是一个概念验证应用程序。它使用SwingWorker
计数从0到99,每次添加一个小延迟。按钮开始计数,在计数期间,允许您将输出的数字加倍。请注意,类成员doubleMe标记为volatile
,因为它是跨线程读取的。
请注意,我使用Java 8来实现紧凑性。
public class MainFrame extends JFrame {
private static final long serialVersionUID = 1L;
public class WorkerTest extends SwingWorker<Void, Integer> {
public volatile boolean doubleMe = false;
protected Void doInBackground() throws Exception {
for(int i=0; i<100; i++) {
publish(doubleMe ? i*2 : i);
Thread.sleep(100);
}
return null;
}
@Override
protected void process(List<Integer> numberList) {
super.process(arg0);
numberList.forEach(System.out::println);
}
}
private WorkerTest worker = null;
private final JButton btn;
public MainFrame() {
setMinimumSize(new Dimension(200, 100));
btn = new JButton("Go!");
btn.addActionListener(ae -> {
if(worker == null || worker.isDone()) {
btn.setText("Toggle double!");
worker = new WorkerTest();
worker.addPropertyChangeListener(l -> {
if("state".equals(l.getPropertyName()) && StateValue.DONE.equals(l.getNewValue())) {
btn.setText("Go!");
}
});
worker.execute();
} else {
worker.doubleMe = !worker.doubleMe;
}
});
add(btn);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MainFrame mf = new MainFrame();
mf.setVisible(true);
});
}
}
在你的情况下,你会读数字,而不是生成数字,但概念是相同的。 doubleMe充当一种与线程通信的方式,以便在线程仍在工作时改变其行为。如果这回答了你的问题,请告诉我。
答案 1 :(得分:0)
我猜你正在寻找的是一种天真的方法,可以通过实时数字流取平均值。
您可以这样做:
private int sum = 0; private int n = 0; //没有。 nums阅读
func(){
while / for:
nextNum = // code to read number in a loop
sum += nextNum;
n++;
}
然后您可以使用事件处理程序来捕获按钮单击事件 并在按钮单击时,您可以返回avg = sum / n。
然而,正如Neil指出的那样,如果你想要不间断的流并且还要避免竞争条件,你应该使用线程。
编辑:根据竞争条件,我的意思是假设您在更新总和值但未更新n时单击。在这种情况下,你会得到错误的平均结果。