Java是否具有Integer,Float,Double,Long的可变类型?

smu*_*kes 70 java integer numbers mutable built-in

我处在一种情况,我想使用像Integer这样的可变版本.我是否必须使用这些类(下面)或者Java内置了什么?

http://www.java2s.com/Code/Java/Data-Type/Amutableintwrapper.htm

Ale*_*min 81

您可以始终将值包装在数组中,就像int[] mutable = {1};包含可变包装类的代码太麻烦一样.

  • 聪明,丑陋像罪恶. (24认同)
  • 这非常聪明,几乎没有空间.加上避免使用AtomicInt完成的syching. (2认同)

Boz*_*zho 49

不,Java没有这些内置.这是有原因的.使用可变类型很危险,因为它们很容易被滥用.此外,它实现起来非常简单.例如,commons-lang有一个MutableInt.

  • "使用可变类型很危险,因为它们很容易被滥用." 大多数事情都可能被滥用.对于安全性很重要的情况,存在不可变类型,尽管它们可以通过反射来改变.在这些情况下,没有理由阻止人们在需要时使用可变类型. (26认同)
  • 我的猜测是java开发人员希望Integer'行为'就像一个int,这是...你有一个引用它,它永远不会改变(避免混淆).但是......对于我来说,某种方式没有可变选项似乎仍然很奇怪...... (3认同)
  • 更好的方式是,不可变类型在例如地图和集合中产生较少的混淆.如果你有一个可变的整数并且在它作为一个键的位置改变了它的值,它会搞乱这个集合.但是,如果你需要一些可变的Integer实现,没有什么比创建一个内部有int值的类更容易了.而且你可以在那里发挥创造力 - 让它成为一个反击或倒计时,而不仅仅是一个能够完成任何事情的普通int.给它一些逻辑(除非你在Java EE中开发底层工作). (2认同)

小智 41

既然JDK 1.5 java现在有了 java.util.concurrent.atomic.AtomicInteger

这是一个线程安全的可变整数,使用示例:

final AtomicInteger value = new AtomicInteger(0);
Run Code Online (Sandbox Code Playgroud)

然后是:

value.incrementAndGet();
Run Code Online (Sandbox Code Playgroud)

  • 这种安全性会带来性能成本,在许多情况下并不需要.例如,我的常见用例是增加由lambda捕获的计数器.使用原子是过度的. (7认同)

Vin*_*ior 9

这是我为可变整数制作的一个小类:

public class MutableInteger {
    private int value;
    public MutableInteger(int value) {
        this.value = value;
    }
    public void set(int value) {
        this.value = value;
    }
    public int intValue() {
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以轻松地将其扩展到任何其他原语.当然,就像其他人一样,你应该小心使用它.


Pet*_*rey 7

你可以使用nnnn []作为任何原始类型的可变对象,如@Alexandre所暗示,java也有AtomicInteger和AtomicLong.

恕我直言通常是一个比整数更好的选择,这是可变的.

你能否详细了解为什么需要一个mutliple对象,也许还有另一种方法来实现同样的东西.

  • 说原始类型是**可变**并不是真的有效.它可以被**改变**但是如果你只指向一个新对象,那么每个非最终对象也可以改变**.例如`Integer a = 4;`然后`a = 5;`是有效代码,但`Integer`是不可变的. (15认同)
  • int不可变. (6认同)
  • `int`总是可变的,除非它也是`final` (6认同)
  • `int` 是不可变的,因为如果将它传递给方法,该方法就无法更改其值并将新值反映在调用方法中 (2认同)

Dir*_*cht 5

AtomicInteger已被提及.Double可以模拟可变的s AtomicReference<Double>.已经提到的警告适用,它是不好的风格,但有时你有这样的代码

double sum=0
for (Data data:someListGenerator())
  sum+=data.getValue()
Run Code Online (Sandbox Code Playgroud)

并希望以功能Java 8风格重构它.如果代码遵循此模式但增加了相当大的复杂性,则最明智的转换可能

AtomicReference<Double> sumref=new AtomicReference<>(0d);
someStreamGenerator().forEach(data->
  sumref.set(sumref.get().doubleValue()+data.getValue()));
double sum=sumref.get().doubleValue();
Run Code Online (Sandbox Code Playgroud)

当然,这至少是一种可疑的风格.但是,我发现自己不止一次出现在ResultSet计算机上扭曲循环的情况,并且部分累积了三种不同的信息.这使得将代码转换为适当的功能样式变得非常困难.根据上述模式转换累积部分在我看来是干净的代码和过度简化的重构之间的合理权衡.