2011-08-25 80 views
7

我正在处理一个需要我具有数组的字符串表示形式的项目。问题是有这个重复的代码,我敢肯定可以以某种方式重构,但我还没有找到。检测数组是否包含整数或双精度值

private static String printDoubleArray(String title, double[] array){ 
    String result = title; 
    for (double d : array) { 
     result += d + " "; 
    } 
    return result; 
} 

private static String printIntArray(String title, int[] array){ 
    String result = title; 
    for (int d : array) { 
     result += d + " "; 
    } 
    return result; 
} 

在此先感谢。

+1

我认为你必须忍受重复。所有的JDK API都是这样做的。你应该做的是使用StringBuilders。 – Thilo

+0

如果你想减少重复,你可以尝试使用Arrays.toString(double [])和Arrays.toString(int []);) –

+0

Java泛型的问题是它不支持原语。因为这个原因,我已经多次看到人们实现他们自己的'IntSet','DoubleSet',[为了防止拳击开销] ...不仅他们不能使用java.util。集合“,他们也必须复制代码,因为与原语相同的问题。 – amit

回答

2

为什么不使用的方法Arrays.toString(...)java.util包吗?

int[] intArray = {1, 2, 4}; 
double[] doubleArray = {1.1, 2.2, 4.4}; 
System.out.println(Arrays.toString(intArray)); 
System.out.println(Arrays.toString(doubleArray)); 
+0

一个很好的方法,但我需要控制输出的格式 –

+0

使用查找和替换文本方法。你可以用''“替换'','''',然后删除'['和']'字符以获得你在问题中提供的输出。 –

0

您可以使用包装类Integer和Double替代int和double。使用它们的基类写入一个方法Number

+3

不幸的是,我们不能将'double []''转换成'Double []'(例如),所以我们必须创建一个新的包装数组并且一个接一个地复制所有的值 - 为此,我们必须分离处理每个原语的数组并创建重复的代码;)(顺便说一句 - 有同样的想法) –

+0

为什么downvote。答案在技术上是正确的(尽管它可能不是OP正在寻找的东西)。 – sleske

4

您可以使用java.lang.reflect.Array,它允许访问阵列中任何时间的元素。见get(arr, index)getLength(arr)

+0

然后他的方法签名将是'printArray(String title,Object intOrDoubleArray')?似乎放弃了类型安全(可能还有一些运行时反射的性能)。 – Thilo

+0

@Thilo:是的,没错。这就是你在Java中使用基元的原因。在Java中,原语确实是原始的,并且不享受“真实”类型所带来的许多好处,例如多态。 – sleske

2

你的问题的解决方案是这样的:

public class Test { 

    public static String numberArrayToString(Number[] arr) { 

     if (arr == null) return ""; 

     StringBuilder sb = new StringBuilder(); 

     for (Number n : arr) { 
      sb.append(n.toString()).append(" "); 
     } 

     return sb.toString(); 

    } 

    public static void main(String[] args) { 

     Integer[] intArr = { 1, 4, 6, 7 }; 
     Double[] dblArr = { 33.44, 55.66, 11.22 }; 

     System.out.println(numberArrayToString(intArr)); 
     System.out.println(numberArrayToString(dblArr)); 

    } 

} 

它产生这样的:

1 4 6 7 
33.44 55.66 11.22 

但是,如果你定义一个盒装元的阵列(仅适用即子类Number),但不包含原语(即,int[]double[])。

问题是,使用盒装原语确实效率低下。

+1

如何将现有的int []和double []转换为Integer []或Double []? [提示:代码重复] – amit

+1

这是整个问题,你将不得不创建一个新的int []并通过Integer []循环,这也是完全没有效率的。现实是:你应该实现你的方法的多个版本。 – JVerstry

+0

Arrays.toString()可以帮助你,但它的格式不一样... – JVerstry

1

使用guava,您可以使用Ints将基本数组(int [])转换为包装类型列表(List)。此外,您可以使用Joiner

Joiner.on(' ').join(Ints.asList(new int[]{1,2,3})); 

的方法则是:

void printIntArray(String title, int[] array) { 
    printArray(title, Ints.asList(array)); 
} 

String printArray(String title, Iterable<? extends Number> asList){ 
    return title + " " + Joiner.on(' ').join(asList); 
} 
2

我会使用commons-lang创建字符串创建使用Object[]数组作为这样

int[] intArray = ...; 
String str = printArray(title, ArrayUtils.toObject(intArray)); 

double[] doubleArray = ...; 
String str = printArray(title, ArrayUtils.toObject(doubleArray)); 

public static void printArray(String title, Object[] array) { 
    return title + " " + StringUtils.join(array, " "); 
} 

注打印方法,这在内部将复制的阵列,其将框的整数到整数对象,所以如果数组的性能/大小是一个问题,我会硬着头皮为基元类型创建方法,但我会调用所有方法printArray并用不同的类型重载它。

编辑:

相反公地郎,你可以使用Guava元,这将不会复制阵列(但是会autobox在列表中的彩车),所以你可以这样做:

int[] intArray = ...; 
String str = printArray(title, Ints.asList(intArray)); 

double[] doubleArray = ...; 
String str = printArray(title, Floats.asList(doubleArray)); 
相关问题