2011-08-25 19 views
7

Estoy trabajando en un proyecto que requiere que tenga una representación de cadena de una matriz. El problema es tener este código duplicado, que estoy seguro puede ser refactorizado de alguna manera, pero aún no he encontrado uno.Detectar si una matriz contiene un número entero o doble

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; 
} 

Gracias de antemano.

+1

Creo que tienes que vivir con la duplicación. Todas las API de JDK hacen lo mismo. Sin embargo, lo que debes hacer es usar StringBuilders. – Thilo

+0

Si desea reducir el duplicado, puede intentar usar Arrays.toString (double []) y Arrays.toString (int []);) –

+0

el problema con Java Generics es que no admite primitivas. por esta razón, he visto muchas veces que las personas implementan su propio 'IntSet',' DoubleSet', [para evitar el gasto general del boxeo] ... no solo no pueden usar 'java.util.Colección', también tienen que duplicar el código, debido al mismo problema que tiene con los primitivos. – amit

Respuesta

2

Por qué no utilizar uno de los métodos de Arrays.toString(...)java.util paquete?

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

Un buen enfoque, pero necesitaría controlar el formato de la salida –

+0

Utilice un método de búsqueda y reemplazo de texto. Podría reemplazar '", "' con '" "', y luego eliminar los caracteres '[' y ']' para tener el resultado que proporcionó en la pregunta. –

0

Puede usar las clases contenedoras Entero y Doble en lugar de int y doble. Escriba un método utilizando su clase base Number

+3

Desafortunadamente, no podemos convertir 'doble []' a 'Doble []' (por ejemplo), así que tendríamos que crear una nueva matriz de envoltura y copiar todos los valores uno por uno, y para eso, tendríamos tiene que manejar cada conjunto de primitivas por separado y crear código duplicado;) (por cierto, tenía la misma idea) –

+0

¿Por qué el voto a favor? La respuesta es técnicamente correcta (aunque puede no ser lo que el OP está buscando). – sleske

4

Puede usar java.lang.reflect.Array que permite el acceso a elementos de cualquier momento de la matriz. Ver get(arr, index), etc. getLength(arr)

+0

Y luego su firma de método sería 'printArray (String title, Object intOrDoubleArray')? Parece que hay que renunciar a la seguridad de tipo (y probablemente algún rendimiento de tiempo de ejecución para la reflexión). – Thilo

+0

@Thilo: Sí, cierto. Eso es lo que obtienes por usar primitivas en Java. Los primitivos realmente son, ehm, primitivos en Java, y no disfrutan de muchos de los beneficios que los tipos "reales" hacen, como el polimorfismo. – sleske

2

La solución a su problema es el siguiente:

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)); 

    } 

} 

Se produce esto:

1 4 6 7 
33.44 55.66 11.22 

Sin embargo, sólo funciona si define sus matrices con las primitivas en caja (es decir, subclases de Number), pero no con primitivas (es decir, int[] y double[]).

El problema es que el uso de primitivas en caja es realmente ineficiente.

+1

¿cómo se convierte existente 'int []' y 'double []' a 'Integer []' o 'Double []'? [sugerencia: duplicación de código] – amit

+1

Ese es todo el problema, tendría que crear un nuevo int [] y un bucle a través de Integer [], que también es totalmente ineficiente. La realidad es: debes implementar una versión múltiple de tu método. – JVerstry

+0

Arrays.toString() puede ayudarlo, pero no es el mismo formato ... – JVerstry

1

Usando guava puedes convertir la matriz primitiva (int []) a una Lista del tipo de envoltura (Lista) usando Ints. Además, puede usar el Joiner.

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

El método es entonces:

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

me gustaría utilizar commons-lang para crear la cadena de crear el método de impresión que utiliza una matriz Object[] como tal

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, " "); 
} 

Nota, esto internamente copiará una matriz que la caja los enteros en objetos enteros, por lo si el rendimiento/tamaño de la matriz es un problema, me quedaría con la bala y crearía métodos para los tipos primitivos, aunque llamaría a todos los métodos printArray y los sobrecargaría con diferentes tipos.

EDIT:

En lugar de commons-lang, podría utilizar Guava primitivas, que no copiará la matriz (sino que simplemente AUTOBOX los flotadores en la lista), por lo que podría hacer:

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

double[] doubleArray = ...; 
String str = printArray(title, Floats.asList(doubleArray)); 
Cuestiones relacionadas