2015-03-02 32 views
0

我目前使用两个类都代表一个数据结构(像一个特殊的缓冲区,但为了简单在这个例子中,让我们假设三字段)工作在本地类型;一个是long,另一个是float(所以两者都在处理本机类型)。为了避免代码加倍,直接的方法是在类型<T>上实现泛型,然后有两个用户,一个用于<long>,一个用于<float>Java中的本机类型(原语)的泛型(或其他方法)

AFAIK这是不可能的本地类型;只有从Object派生的对象才有可能。

有没有其他的方法来避免代码加倍否则不可避免?由于性能方面的原因,使用非本地类型(如Integer)不是一种选择。

当前的代码,剥离下来仅仅有三个字段的小例子:

public class TupleFloat { 
    private float field1; 
    private float field2; 
    private float field3; 
    public TupleFloat(float a, float b, float c) { 
    field1 = a; field2 = b; field3 = c; 
    } 
    public float sum() { 
    return field1 + field2 + field3; 
    } 
} 

public class TupleLong { 
    private long field1; 
    private long field2; 
    private long field3; 
    public TupleLong(long a, long b, long c) { 
    field1 = a; field2 = b; field3 = c; 
    } 
    public long sum() { 
    return field1 + field2 + field3; 
    } 
} 

使用泛型:

public class Tuple<T> { 
    private T field1; 
    private T field2; 
    private T field3; 
    public Tuple<T>(T a, T b, T c) { 
    field1 = a; field2 = b; field3 = c; 
    } 
    public T sum() { 
    return field1 + field2 + field3; 
    } 
} 

但这不会为本地类型工作(Tuple<float> x;)。

有没有其他的方法来避免代码加倍否则不可避免?甚至有可能是一个最佳实践如何解决这样的问题?

+0

你可以简单地使用包装类'Float','Integer', '长'等 – Dragondraikk 2015-03-02 13:23:02

+0

由于性能方面的原因,我只是添加了需要坚持原生类型的信息。 – Alfe 2015-03-02 13:23:56

+0

不可能,因为泛型意味着要与对象一起工作。 – SMA 2015-03-02 13:25:28

回答

1

基元不可能。看看一些内置的API,它们充斥着不同基元的各种版本的方法。理论上讲,你可以有一个具有6个私有变量和所有风格的类,但这看起来比两个单独的“干净”类更丑陋。

你可能可以用Lambdas做些事情来解决这个问题,但我并不确定。

1

原始数字类型不能用作泛型的参数(由于泛型定义的方式)。此外,你定义了sum(),所以我不确定你打算如何处理不是“可以和”的类型。

是的,依靠自动装箱是昂贵的,这是一个不可否认的事实;是的,基元没有对象标识,所以与C#不同,例如不能有List<int>(甚至没有谈论类型擦除)。

这就是为什么Java 8的实现已经定义了例如IntStream来“补充”Stream<Integer>。对你来说,这将意味着定义FloatTupleIntTuple

目前,还没有其他方法在Java中做到这一点...