GVKun编程网logo

接口是Java 8中实用程序类的有效替代品吗?[重复](java中使用接口的好处)

4

本文的目的是介绍接口是Java8中实用程序类的有效替代品吗?[重复]的详细情况,特别关注java中使用接口的好处的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解接口是

本文的目的是介绍接口是Java 8中实用程序类的有效替代品吗?[重复]的详细情况,特别关注java中使用接口的好处的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解接口是Java 8中实用程序类的有效替代品吗?[重复]的机会,同时也不会遗漏关于haskell – Data.Vector.dropWhile的有效替代品、java – 使用枚举实现实用程序类和单例、java – 强制实用程序类应该是final和private构造函数吗?、JavaFX GUI Updater实用程序类中的并发问题的知识。

本文目录一览:

接口是Java 8中实用程序类的有效替代品吗?[重复](java中使用接口的好处)

接口是Java 8中实用程序类的有效替代品吗?[重复](java中使用接口的好处)

在过去十年左右的时间里,我一直在将以下模式用于Java实用程序类。该类仅包含静态方法和字段,已声明final为无法扩展,并且具有private构造函数因此无法实例化。

public final class SomeUtilityClass {    public static final String SOME_CONSTANT = "Some constant";    private SomeUtilityClass() {}    public static Object someUtilityMethod(Object someParameter) {        /* ... */        return null;    }}

现在,随着Java 8
接口中静态方法的引入,我最近发现自己使用了实用程序接口模式:

public interface SomeUtilityInterface {    String SOME_CONSTANT = "Some constant";    static Object someUtilityMethod(Object someParameter) {        /* ... */        return null;    }}

这使我摆脱构造,和大量的关键字(个publicstaticfinal),这些接口中隐含的。

这种方法有不利之处吗?通过实用程序接口使用实用程序类有什么好处?

答案1

小编典典

以为Constant Interface模式创建反模式的人为基础,我想说,尽管您不打算让客户端实现该接口,但它仍然有可能,可能更容易并且 不应被允许

API应该易于使用且难以滥用。做简单的事情应该很容易;可能做复杂的事情; 并且不可能或至少很难做错事。

尽管如下所述,但这确实取决于目标受众


许多易于使用的设计模式都受到了很多批评(上下文模式,单例模式,常量接口模式)。哎呀,甚至像得墨meter耳定律这样的设计原则也因过于冗长而受到批评。

我不想这么说,但是这些决定都是基于意见的。尽管上下文模式被视为一种反模式, 但在诸如Spring和Android SDK之类的主流框架中很明显
。它归结为环境以及目标受众。

我可以找到的主要缺点 是在Constant Interface
wiki中的“缺点”下列出的第三项内容:

如果将来的发行版中要求二进制代码兼容,则常量接口必须永远保持一个接口(无法将其转换为类), 即使它在常规意义上并未用作接口。

如果您曾经想过“嘿,这实际上不是合同,我想执行更强大的设计”,则您将无法对其进行更改。但正如我所说,这取决于您;也许您将来不会在意​​更改它。

最重要的是,@
TagirValeev提到的代码清晰度。接口的目的是实现;如果您不希望某人实现您提供的API,请不要使其实现。但是,我认为这与“目标受众”声明有关。不会撒谎,我会在不太冗长的基础上与您同在,但这取决于我的代码适用于谁。不想使用可能会被检查的代码的常量接口。

haskell – Data.Vector.dropWhile的有效替代品

haskell – Data.Vector.dropWhile的有效替代品

考虑以下:
module Main where

import           Criterion.Main
import qualified Data.Vector    as V

f1 :: V.Vector Double -> Double
f1 xs
  | V.null xs = 0
  | otherwise = V.last xss / V.head xss
    where xss = V.dropWhile (< 10) xs

f2 :: V.Vector Double -> Double
f2 xs
  | V.null xs = 0
  | otherwise = V.last xs / V.head xs

setupEnv :: IO (V.Vector Double)
setupEnv = return $V.enumFromN 0 10000000

main :: IO ()
main = defaultMain [
  env setupEnv $\v ->
    bgroup "funcs" [bench "f1" $nf f1 v,bench "f2" $nf f2 v]
  ]

使用–make -O2进行编译并运行会得到以下结果:

app $./A
benchmarking funcs/f1
time                 81.87 ms   (78.34 ms .. 86.06 ms)
                     0.998 R²   (0.996 R² .. 1.000 R²)
mean                 85.87 ms   (84.16 ms .. 87.13 ms)
std dev              2.351 ms   (1.169 ms .. 3.115 ms)

benchmarking funcs/f2
time                 27.50 ns   (27.11 ns .. 27.95 ns)
                     0.998 R²   (0.996 R² .. 0.999 R²)
mean                 27.62 ns   (27.21 ns .. 28.05 ns)
std dev              1.391 ns   (1.154 ns .. 1.744 ns)
variance introduced by outliers: 73% (severely inflated)

简单地取第一个和最后一个元素并将它们分开的平均执行时间是~27ns.丢弃前9个元素并执行相同操作的平均值约为85毫秒或慢3000倍.

使用未装箱的向量可将f1的性能提高一半以上,但我需要支持没有“UnBoxed”类实例的元素.

根据dropWhile documentation,它具有O(n)的复杂性,但它没有复制. Haskell库中是否有数据结构支持高效的dropWhile类型操作以及对第一个和最后一个元素的O(1)访问?

解决方法

Vector的dropWhile有问题.我认为流融合最有可能无法正确启动,我们支付昂贵的流/捆绑建设费用.可能需要进一步调查.

作为权宜之计,您可以实现自定义dropWhile.我使用以下代码的基准测试:

dropWhile' :: (a -> Bool) -> V.Vector a -> V.Vector a
dropWhile' p v = V.drop (go 0) v where
  go n | n == V.length v       = n
       | p (V.unsafeIndex v n) = go (n + 1)
       | otherwise             = n

并得到以下结果:

benchmarking funcs/f1
time                 57.70 ns   (56.35 ns .. 59.46 ns)

benchmarking funcs/f2
time                 19.68 ns   (19.44 ns .. 19.91 ns)

java – 使用枚举实现实用程序类和单例

java – 使用枚举实现实用程序类和单例

Peter Lawrey在他的博客上写了关于 Two Uses of Enums that most people forget的内容.

首先,我没有忘记 – 我甚至没有意识到:)

这些方法简洁明了 – 与更传统的实现相同方法的方法相比,除了简洁之外还有什么好处,比如使用带有私有构造函数的final类来实现实用程序类?

此外,是否有任何问题(除了令人困惑的程序员不期待它)?

解决方法

我真的不同意该帖子中第一次使用enum.如果您想要一个不可实例化的实用程序类,只需给它一个私有构造函数.就是这么简单,在我看到的那种情况下,枚举没有提供额外的好处.

在实用程序类中使用枚举用于单例是很好的,但我通常会尝试保持枚举被用作内部实现细节的事实.例如,参见Guava的Predicates类,它使用枚举来强制执行某些谓词的单个实例,例如alwaysTrue().但它不会向用户公开枚举.

至于其他好处:是的,还有其他好处,例如内置的可串行化,并且每个类加载器绝对强制执行枚举常量的单个实例,即使在反序列化时也是如此.

java – 强制实用程序类应该是final和private构造函数吗?

java – 强制实用程序类应该是final和private构造函数吗?

通过创建私有构造函数,我们可以避免从外部的任何地方实例化类.通过使类最终,没有其他类可以扩展它.为什么Util类需要私有构造函数和最终类?

解决方法

从功能的角度来看,这不是一个任务,也不是 Java复杂或运行时.但是,其编码标准被更广泛的社区所接受.甚至许多静态代码审查工具(如 checkstyle和许多其他人)都会检查这些类是否遵循此类规定.

为什么遵循这一惯例,已在其他答案中解释,甚至OP也涵盖了这一点.

我想进一步解释一下,大多数Utility类都有与对象实例无关的方法/函数.这些是聚合函数.因为它们仅依赖于返回值的参数而不依赖于实用程序类的类变量.因此,大多数这些函数/方法都是静态的.因此,Utility类理想地是具有所有静态方法的类.
因此,任何调用这些方法的程序员都不需要实例化这个类.然而,一些机器人编码器(可能没有经验或兴趣)将倾向于在调用其方法之前创建他们认为需要的对象.为避免创建对象,我们有3个选项: –

>继续教育人们不要实例化它. (没有理智的人可以继续这样做.)
>将类标记为抽象: –
现在robo-coders再次不会创建对象.然而,审查和更广泛的Java社区将争辩说,标记抽象意味着你希望有人扩展它.所以,这也不是一个好选择.
>私人建设者: –
受保护将再次允许子类创建对象.

现在,再次如果有人想为这些实用程序类添加一些功能的新方法,他不需要扩展它,他可以添加新方法,因为每个方法都是独立的,没有机会破坏其他功能.所以,不需要覆盖它.而且你也不会去见,所以需要将它子类化.最好将其标记为最终.

总之,创建实用程序类的对象没有意义.因此构造函数应该是私有的.而你永远不想覆盖它,所以最后标记它.

JavaFX GUI Updater实用程序类中的并发问题

JavaFX GUI Updater实用程序类中的并发问题

我正在JavaFX中为大型Java项目构建GUI。这个项目有许多不同的工作线程在后台执行一些繁重的计算,我试图在GUI中可视化这些工作线程的进度。所谓进步,是指不仅是裸露的百分比,而且是Task类中未包含的其他变量,例如:

  • 当前文件
  • 当前错误计数
  • 到目前为止读取的字节数

由于这些进度变量的变化非常快,并且由于必须从JavaFX线程(Platform.runLater())执行GUI更新,因此JavaFX事件队列很快就会过载。我正在尝试通过构建实用程序类来解决此问题,该实用程序类能够从JavaFX线程外部异步更新GUI属性。应该跳过快速连续的更新,以便仅显示最新值,从而避免用Runnables挤满JavaFX事件队列。

因此,我构建了以下类GUIUpdater以将Properties(通常是GUI元素,如Label)绑定到ObservableValues(例如SimpleStringProperty)。此类具有两个InnerClasses:

  • PropertyUpdater负责将单个Property绑定到单个ObservableValue并进行更新。
  • Updater提供了用于Platform.runLater可重复使用的Runnable对象()。

实用程序类:

package main;import java.util.concurrent.ConcurrentLinkedQueue;import javafx.application.Platform;import javafx.beans.property.Property;import javafx.beans.value.ChangeListener;import javafx.beans.value.ObservableValue;/** * Class for enabling fast updates of GUI components from outside the JavaFX thread. *  Updating GUI components (such as labels) should be done from the JavaFX thread by using Platform.runLater for example. *  This makes it hard to update the GUI with a fast changing variable as it is very easy to fill up the JavaFX event queue faster than it can be emptied (i.e. faster than it can be drawn). *  This class binds ObservableValues to (GUI) Properties and ensures that quick consecutive updates are ignored, only updating to the latest value. */public class GUIUpdater {    private ConcurrentLinkedQueue<PropertyUpdater<?>>   dirtyPropertyUpdaters   =   new ConcurrentLinkedQueue<>();    private Updater                                     updater                 =   new Updater();    private boolean                                     isUpdating              =   false;    /**     * Binds an ObservableValue to a Property.     *  Updates to the ObservableValue can be made from outside the JavaFX thread and the latest update will be reflected in the Property.     * @param property      (GUI) Property to be updated/     * @param observable    ObservableValue to update the GUI property to.     */    public <T> void bind(Property<T> property, ObservableValue<T> observable) {        PropertyUpdater<T>  propertyUpdater = new PropertyUpdater<>(property, observable);        observable.addListener(propertyUpdater);    }    /**     * Unbinds the given ObservableValue from the given Property.     *  Updates to the ObservableValue will no longer be reflected in the Property.     * @param property      (GUI) Property to unbind the ObservableValue from.     * @param observable    ObservableValue to unbind from the given Property.     */    public <T> void unbind(Property<T> property, ObservableValue<T> observable) {        PropertyUpdater<T>  tmpPropertyUpdater = new PropertyUpdater<>(property, observable);        observable.removeListener(tmpPropertyUpdater);    }    /**     * Schedules an update to the GUI by using a call to Platform.runLater().     *  The updated property is added to the dirtyProperties list, marking it for the next update round.     *  Will only submit the event to the event queue if the event isn''t in the event queue yet.     * @param updater     */    private void scheduleUpdate(PropertyUpdater<?> updater) {        this.dirtyPropertyUpdaters.add(updater);        // Make sure the isUpdating var isn''t changed concurrently by the Updater thread (on the JavaFX event queue)        synchronized (this) {            if (!this.isUpdating) {                this.isUpdating = true;                Platform.runLater(this.updater);            }        }    }    /**     * Class used for binding a single ObservableValue to a Property and updating it.     *     * @param <T>     */    private class PropertyUpdater<T> implements ChangeListener<T> {        private boolean             isDirty     =   false;        private Property<T>         property    =   null;        private ObservableValue<T>  observable  =   null;        public PropertyUpdater(Property<T> property, ObservableValue<T> observable) {            this.property = property;            this.observable = observable;        }        @Override        /**         * Called whenever the ObservableValue has changed. Marks this Updater as dirty.         */        public synchronized void changed(ObservableValue<? extends T> observable, T oldValue, T newValue) {            if (!this.isDirty) {                this.isDirty = true;                GUIUpdater.this.scheduleUpdate(this);            }        }        /**         * Updates the Property to the ObservableValue and marks it as clean again.         *  Should only be called from the JavaFX thread.         */        public synchronized void update() {            T value = this.observable.getValue();            this.property.setValue(value);            this.isDirty = false;        }        @Override        /**         * Two PropertyUpdaters are equals if their Property and ObservableValue map to the same object (address).         */        public boolean equals(Object otherObj) {            PropertyUpdater<?>  otherUpdater = (PropertyUpdater<?>) otherObj;            if (otherObj == null) {                return false;            } else {                // Only compare addresses (comparing with equals also compares contents):                return (this.property == otherUpdater.property) && (this.observable == otherUpdater.observable);            }        }    }    /**     * Simple class containing the Runnable for the call to Platform.runLater.     *  Hence, the run() method should only be called from the JavaFX thread.     *     */    private class Updater implements Runnable {        @Override        public void run() {            // Loop through the individual PropertyUpdaters, updating them one by one:            while(!GUIUpdater.this.dirtyPropertyUpdaters.isEmpty()) {                PropertyUpdater<?>  curUpdater = GUIUpdater.this.dirtyPropertyUpdaters.poll();                curUpdater.update();            }            // Make sure we''re not clearing the mark when scheduleUpdate() is still setting it:            synchronized (GUIUpdater.this) {                GUIUpdater.this.isUpdating = false;            }        }    }}

这是测试GUIUpdater实用程序类的简单类:

package main;import javafx.application.Application;import javafx.beans.property.SimpleStringProperty;import javafx.concurrent.Task;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.control.ProgressBar;import javafx.scene.layout.FlowPane;import javafx.stage.Stage;public class JavaFXTest extends Application {    private GUIUpdater  guiUpdater  =   new GUIUpdater();    private Label       lblState    =   new Label();    private ProgressBar prgProgress =   new ProgressBar();    public static void main(String args[]) {        JavaFXTest.launch(args);    }    @Override    public void start(Stage primaryStage) throws Exception {        // Init window:        FlowPane    flowPane = new FlowPane();        primaryStage.setScene(new Scene(flowPane));        primaryStage.setTitle("JavaFXTest");        // Add a Label and a progressBar:        flowPane.getChildren().add(this.lblState);        flowPane.getChildren().add(this.prgProgress);        // Add button:        Button  btnStart = new Button("Start");        btnStart.setOnAction(new EventHandler<ActionEvent>() {            @Override            public void handle(ActionEvent event) {                // Create task:                TestTask    testTask = new TestTask();                // Bind:                JavaFXTest.this.guiUpdater.bind(JavaFXTest.this.lblState.textProperty(), testTask.myStateProperty());                JavaFXTest.this.prgProgress.progressProperty().bind(testTask.progressProperty());   // No need to use GUIUpdater here, Task class provides the same functionality for progress.                // Start task:                Thread  tmpThread = new Thread(testTask);                tmpThread.start();            }        });        flowPane.getChildren().add(btnStart);        // Show:        primaryStage.show();    }    /**     * A simple task containing a for loop to simulate a fast running and fast updating process.     * @author DePhille     *     */    private class TestTask extends Task<Void> {        private SimpleStringProperty    myState =   new SimpleStringProperty();        @Override        protected Void call() throws Exception {            // Count:            try {                int maxValue = 1000000;                System.out.println("Starting...");                for(int i = 0; i < maxValue; i++) {                    this.updateProgress(i, maxValue - 1);                    this.myState.set("Hello " + i);                }                System.out.println("Done!");                } catch(Exception e) {                e.printStackTrace();            }            // Unbind:            JavaFXTest.this.guiUpdater.unbind(JavaFXTest.this.lblState.textProperty(), this.myStateProperty());            return null;        }        public SimpleStringProperty myStateProperty() {            return this.myState;        }    }}

代码的问题是,有时Label不会更新为最新值(在这种情况下为999999)。似乎大多数情况是在应用程序启动后立即发生的,因此,启动应用程序,单击“开始”按钮,关闭它,然后重复此过程,应在尝试几次后重现该问题。据我所知,我synchronized在需要的地方添加了块,这就是为什么我不明白问题出在哪里的原因。

即使我主要是在寻找所描述问题的解决方案,也非常感谢所有建议(甚至那些与问题无关的建议)!我也在代码中添加了注释,因此,我希望与上面的信息一起提供有关问题和代码的足够详细信息。

提前致谢!

答案1

小编典典

我自己可以解决此问题。System.out在各个地方添加几天后,结果发现问题出在isUpdating变量的并发问题上。当JavaFX线程位于while循环和中的synchronized块之间时,发生了问题Updater.run。我通过使Updater.runGUIUpdater.scheduleUpdate方法在同一对象上同步来解决了这个问题。

我也将其GUIUpdater制成了仅静态对象,因为Runnables无论其他GUIUpdater实例如何,都有多个实例将放置在JavaFX事件队列中,从而阻塞了事件队列。总而言之,这是结果GUIUpdater类:

package be.pbeckers.javafxguiupdater;import java.util.concurrent.ConcurrentLinkedQueue;import javafx.application.Platform;import javafx.beans.property.Property;import javafx.beans.value.ChangeListener;import javafx.beans.value.ObservableValue;/** * Class for enabling fast updates of GUI components from outside the JavaFX thread. *  Updating GUI components (such as labels) should be done from the JavaFX thread by using Platform.runLater for example. *  This makes it hard to update the GUI with a fast changing variable as it is very easy to fill up the JavaFX event queue faster than it can be emptied (i.e. faster than it can be drawn). *  This class binds ObservableValues to (GUI) Properties and ensures that quick consecutive updates are ignored, only updating to the latest value. */public abstract class GUIUpdater {    private static  ConcurrentLinkedQueue<PropertyUpdater<?>>   dirtyPropertyUpdaters   =   new ConcurrentLinkedQueue<>();    private static  Updater                                     updater                 =   new Updater();    private static  boolean                                     isUpdating              =   false;    /**     * Binds an ObservableValue to a Property.     *  Updates to the ObservableValue can be made from outside the JavaFX thread and the latest update will be reflected in the Property.     * @param property      (GUI) Property to be updated/     * @param observable    ObservableValue to update the GUI property to.     */    public static <T> void bind(Property<T> property, ObservableValue<T> observable) {        PropertyUpdater<T>  propertyUpdater = new PropertyUpdater<>(property, observable);        observable.addListener(propertyUpdater);    }    /**     * Unbinds the given ObservableValue from the given Property.     *  Updates to the ObservableValue will no longer be reflected in the Property.     * @param property      (GUI) Property to unbind the ObservableValue from.     * @param observable    ObservableValue to unbind from the given Property.     */    public static <T> void unbind(Property<T> property, ObservableValue<T> observable) {        PropertyUpdater<T>  tmpPropertyUpdater = new PropertyUpdater<>(property, observable);        observable.removeListener(tmpPropertyUpdater);    }    /**     * Schedules an update to the GUI by using a call to Platform.runLater().     *  The updated property is added to the dirtyProperties list, marking it for the next update round.     *  Will only submit the event to the event queue if the event isn''t in the event queue yet.     * @param updater     */    private static synchronized void scheduleUpdate(PropertyUpdater<?> updater) {        GUIUpdater.dirtyPropertyUpdaters.add(updater);        if (!GUIUpdater.isUpdating) {            GUIUpdater.isUpdating = true;            Platform.runLater(GUIUpdater.updater);        }    }    /**     * Class used for binding a single ObservableValue to a Property and updating it.     *     * @param <T>     */    private static class PropertyUpdater<T> implements ChangeListener<T> {        private boolean             isDirty     =   false;        private Property<T>         property    =   null;        private ObservableValue<T>  observable  =   null;        public PropertyUpdater(Property<T> property, ObservableValue<T> observable) {            this.property = property;            this.observable = observable;        }        @Override        /**         * Called whenever the ObservableValue has changed. Marks this Updater as dirty.         */        public synchronized void changed(ObservableValue<? extends T> observable, T oldValue, T newValue) {            if (!this.isDirty) {                this.isDirty = true;                GUIUpdater.scheduleUpdate(this);            }        }        /**         * Updates the Property to the ObservableValue and marks it as clean again.         *  Should only be called from the JavaFX thread.         */        public synchronized void update() {            T value = this.observable.getValue();            this.property.setValue(value);            this.isDirty = false;        }        @Override        /**         * Two PropertyUpdaters are equals if their Property and ObservableValue map to the same object (address).         */        public boolean equals(Object otherObj) {            PropertyUpdater<?>  otherUpdater = (PropertyUpdater<?>) otherObj;            if (otherObj == null) {                return false;            } else {                // Only compare addresses (comparing with equals also compares contents):                return (this.property == otherUpdater.property) && (this.observable == otherUpdater.observable);            }        }    }    /**     * Simple class containing the Runnable for the call to Platform.runLater.     *  Hence, the run() method should only be called from the JavaFX thread.     *     */    private static class Updater implements Runnable {        @Override        public void run() {            synchronized (GUIUpdater.class) {                // Loop through the individual PropertyUpdaters, updating them one by one:                while(!GUIUpdater.dirtyPropertyUpdaters.isEmpty()) {                    PropertyUpdater<?>  curUpdater = GUIUpdater.dirtyPropertyUpdaters.poll();                    curUpdater.update();                }                // Mark as updated:                GUIUpdater.isUpdating = false;                          }        }    }}

这是测试器类的稍有更新的版本(由于它完全不重要,因此我不对其进行详细介绍):

package be.pbeckers.javafxguiupdater.test;import be.pbeckers.javafxguiupdater.GUIUpdater;import javafx.application.Application;import javafx.beans.property.SimpleStringProperty;import javafx.concurrent.Task;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.control.ProgressBar;import javafx.scene.layout.FlowPane;import javafx.stage.Stage;public class JavaFXTest extends Application {    private Label       lblCurFile      =   new Label();    private Label       lblErrors       =   new Label();    private Label       lblBytesParsed  =   new Label();    private ProgressBar prgProgress     =   new ProgressBar();    public static void main(String args[]) {        JavaFXTest.launch(args);    }    @Override    public void start(Stage primaryStage) throws Exception {        // Init window:        FlowPane    flowPane = new FlowPane();        primaryStage.setScene(new Scene(flowPane));        primaryStage.setTitle("JavaFXTest");        // Add a few Labels and a progressBar:        flowPane.getChildren().add(this.lblCurFile);        flowPane.getChildren().add(this.lblErrors);        flowPane.getChildren().add(this.lblBytesParsed);        flowPane.getChildren().add(this.prgProgress);        // Add button:        Button  btnStart = new Button("Start");        btnStart.setOnAction(new EventHandler<ActionEvent>() {            @Override            public void handle(ActionEvent event) {                // Create task:                TestTask    testTask = new TestTask();                // Bind:                GUIUpdater.bind(JavaFXTest.this.lblCurFile.textProperty(), testTask.curFileProperty());                GUIUpdater.bind(JavaFXTest.this.lblErrors.textProperty(), testTask.errorsProperty());                GUIUpdater.bind(JavaFXTest.this.lblBytesParsed.textProperty(), testTask.bytesParsedProperty());                JavaFXTest.this.prgProgress.progressProperty().bind(testTask.progressProperty());   // No need to use GUIUpdater here, Task class provides the same functionality for progress.                // Start task:                Thread  tmpThread = new Thread(testTask);                tmpThread.start();            }        });        flowPane.getChildren().add(btnStart);        // Show:        primaryStage.show();    }    /**     * A simple task containing a for loop to simulate a fast running and fast updating process.     * @author DePhille     *     */    private class TestTask extends Task<Void> {        private SimpleStringProperty    curFile     =   new SimpleStringProperty();        private SimpleStringProperty    errors      =   new SimpleStringProperty();        private SimpleStringProperty    bytesParsed =   new SimpleStringProperty();        @Override        protected Void call() throws Exception {            // Count:            try {                int maxValue = 1000000;                long startTime = System.currentTimeMillis();                System.out.println("Starting...");                for(int i = 0; i < maxValue; i++) {                    this.updateProgress(i, maxValue - 1);                    // Simulate some progress variables:                    this.curFile.set("File_" + i + ".txt");                    if ((i % 1000) == 0) {                        //this.errors.set("" + (i / 1000) + " Errors");                    }                    //this.bytesParsed.set("" + (i / 1024) + " KBytes");                }                long stopTime = System.currentTimeMillis();                System.out.println("Done in " + (stopTime - startTime) + " msec!");            } catch(Exception e) {                e.printStackTrace();            }            // Unbind:            GUIUpdater.unbind(JavaFXTest.this.lblCurFile.textProperty(), this.curFileProperty());            GUIUpdater.unbind(JavaFXTest.this.lblErrors.textProperty(), this.errorsProperty());            GUIUpdater.unbind(JavaFXTest.this.lblBytesParsed.textProperty(), this.bytesParsedProperty());            return null;        }        public SimpleStringProperty curFileProperty() {            return this.curFile;        }        public SimpleStringProperty errorsProperty() {            return this.errors;        }        public SimpleStringProperty bytesParsedProperty() {            return this.bytesParsed;        }    }}

我们今天的关于接口是Java 8中实用程序类的有效替代品吗?[重复]java中使用接口的好处的分享已经告一段落,感谢您的关注,如果您想了解更多关于haskell – Data.Vector.dropWhile的有效替代品、java – 使用枚举实现实用程序类和单例、java – 强制实用程序类应该是final和private构造函数吗?、JavaFX GUI Updater实用程序类中的并发问题的相关信息,请在本站查询。

本文标签: