简体   繁体   中英

Convert a string of numbers into an array

i'm having problems creating a program that converts a string of numbers into an array.

i know there is a similar question on here, but all i have to work with is a set of numbers such as [10 15 16 0 57 438 57 18]

heres what i have so far:

import java.util.Scanner;
public class Histogram {

   public static void main(String[] args) {
     Scanner keyboard = new Scanner(System.in);
     String numbers;


     numbers = keyboard.next();
     System.out.println(numbers);

     int [] n1 = new int [numbers.length()];



     for(int n = 0; n < numbers.length(); n++) {
        n1[n] = Integer.parseInt(numbers.split(" ")[n]);
     }


}
}

this code throws throws an exception:

10 15 20 25 30
10
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Histogram.main(Histogram.java:18)

what am i doing wrong? i want to avoid using commas to separate the elements. can anyone explain why the exception is being thrown and how to fix it? i want to understand more than anything.

You should split the string once and store the array somewhere.

Here you are iterating up to the number of characters in the string, not the number of space-separated numbers.

int [] n1 = new int [numbers.length()];
for(int n = 0; n < numbers.length(); n++) {
   n1[n] = Integer.parseInt(numbers.split(" ")[n]);
}

Change to:

String[] parts = numbers.split(" ");
int[] n1 = new int[parts.length];
for(int n = 0; n < parts.length; n++) {
   n1[n] = Integer.parseInt(parts[n]);
}

See it working online: ideone

Here is what is happening:

     numbers = keyboard.next();
     System.out.println(numbers);

//This line is creating an array with the length in characters of the String which in this case is 14
     int [] n1 = new int [numbers.length()];


//Then When you split the number there is really only 5 elements, yet numbers.length() is 14, therefore when asking for the array on position 6 it causes the exception.
     for(int n = 0; n < numbers.length(); n++) {
        n1[n] = Integer.parseInt(numbers.split(" ")[n]);

Aditionally you should just do this operation numbers.split(" ") once, and then just access it like this:

String [] stringParts = numbers.split(" "):

stringParts[n]

So basically your for is really something like this:

for(int n = 0; n < 14; n++)
{

}

and then numbers.split(" ") returns only 5 elements, since there is a total of 5 numbers, so when you ask for position 6, the exception is thrown as the array is only of size 5.

I created this class for my own personal use but i think it can help you with your problem.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class ArrayUtils {

    private static final Logger log = LoggerFactory.getLogger(ArrayUtils.class);
    private static final Map<Class, Class> primitiveMapping = new HashMap<Class, Class>();
    private static final Map<Class, Method> primitiveParseMethodLookup = new HashMap<Class, Method>();
    private static final Map<Class, Method> primitiveArrayGetMethodLookup = new HashMap<Class, Method>();
    private static final Map<Class, Method> valueOfMethodLookup = new HashMap<Class, Method>();

    static {

        // Initialize primitive mappings
        primitiveMapping.put(boolean.class, Boolean.class);
        primitiveMapping.put(byte.class, Byte.class);
        primitiveMapping.put(short.class, Short.class);
        primitiveMapping.put(int.class, Integer.class);
        primitiveMapping.put(float.class, Float.class);
        primitiveMapping.put(long.class, Long.class);
        primitiveMapping.put(double.class, Double.class);

        // Initialize parse, valueOf and get method lookup
        // We do that in advance because the lookup of the method takes the longest time
        // Compared to the normal method call it's 20x higher
        // So we use just the reflective method call which takes double the time of a normal method call
        try {
            primitiveParseMethodLookup.put(boolean.class, Boolean.class.getMethod("parseBoolean", new Class[]{String.class}));
            primitiveParseMethodLookup.put(byte.class, Byte.class.getMethod("parseByte", new Class[]{String.class}));
            primitiveParseMethodLookup.put(short.class, Short.class.getMethod("parseShort", new Class[]{String.class}));
            primitiveParseMethodLookup.put(int.class, Integer.class.getMethod("parseInt", String.class));
            primitiveParseMethodLookup.put(float.class, Float.class.getMethod("parseFloat", String.class));
            primitiveParseMethodLookup.put(long.class, Long.class.getMethod("parseLong", String.class));
            primitiveParseMethodLookup.put(double.class, Double.class.getMethod("parseDouble", String.class));

            valueOfMethodLookup.put(Boolean.class, Boolean.class.getMethod("valueOf", new Class[]{String.class}));
            valueOfMethodLookup.put(Byte.class, Byte.class.getMethod("valueOf", new Class[]{String.class}));
            valueOfMethodLookup.put(Short.class, Short.class.getMethod("valueOf", new Class[]{String.class}));
            valueOfMethodLookup.put(Integer.class, Integer.class.getMethod("valueOf", String.class));
            valueOfMethodLookup.put(Float.class, Float.class.getMethod("valueOf", String.class));
            valueOfMethodLookup.put(Long.class, Long.class.getMethod("valueOf", String.class));
            valueOfMethodLookup.put(Double.class, Double.class.getMethod("valueOf", String.class));

            primitiveArrayGetMethodLookup.put(boolean.class, Array.class.getMethod("getBoolean", new Class[]{Object.class, int.class}));
            primitiveArrayGetMethodLookup.put(byte.class, Array.class.getMethod("getByte", new Class[]{Object.class, int.class}));
            primitiveArrayGetMethodLookup.put(short.class, Array.class.getMethod("getShort", new Class[]{Object.class, int.class}));
            primitiveArrayGetMethodLookup.put(int.class, Array.class.getMethod("getInt", Object.class, int.class));
            primitiveArrayGetMethodLookup.put(float.class, Array.class.getMethod("getFloat", Object.class, int.class));
            primitiveArrayGetMethodLookup.put(long.class, Array.class.getMethod("getLong", Object.class, int.class));
            primitiveArrayGetMethodLookup.put(double.class, Array.class.getMethod("getDouble", Object.class, int.class));
        } catch (NoSuchMethodException e) {

            //******************************
            // This can never happen
            //******************************
        }

    }

    public static boolean isArrayOfPrimitives(Object object) {

        if (object.getClass().isArray()) {
            return object.getClass().getComponentType().isPrimitive();
        }

        return false;
    }

    public static boolean isArrayOf(Object object, Class clazz) {

        if (object.getClass().isArray()) {
            return clazz.isAssignableFrom(object.getClass().getComponentType());
        }

        return false;
    }

    /**
     * Convert any array of primitives(excluding char), strings or numbers into any other array
     * of strings or numbers.
     *
     * @param array                       Array of primitives(excluding char), strings or numbers
     * @param convertedArrayComponentType Converted array component type (String or Number)
     * @param <T>                         To allow implicit casting
     * @return Array of convertedArrayComponentType
     */
    public static <T> T[] convertArray(Object array, Class<T> convertedArrayComponentType) {

        // Collect data regarding arguments
        final boolean arrayOfPrimitives = isArrayOfPrimitives(array);
        final boolean arrayOfCharPrimitives = isArrayOf(array, char.class);
        final boolean arrayOfCharacters = isArrayOf(array, Character.class);
        final boolean arrayOfStrings = isArrayOf(array, String.class);
        final boolean arrayOfNumbers = isArrayOf(array, Number.class);

        // Check if array is an array of strings, primitives or wrapped primitives
        if (!arrayOfPrimitives && !arrayOfNumbers && !arrayOfStrings || arrayOfCharPrimitives || arrayOfCharacters) {
            throw new IllegalArgumentException(array + " must be an array of of strings, primitives or boxed primitives (byte, boolean, short, int, float, long, double)");
        }

        // Check if it's assignable from Number of String
        if (!Number.class.isAssignableFrom(convertedArrayComponentType) && !String.class.isAssignableFrom(convertedArrayComponentType)) {
            throw new IllegalArgumentException(convertedArrayComponentType + " must be a Number or a String");
        }

        try {
            return (T[]) convertArrayInternal(array, convertedArrayComponentType);
        } catch (InvocationTargetException e) {

            // This can happen due to errors in conversion
            throw (RuntimeException) e.getTargetException();
        } catch (Exception e) {

            // This should never happen
            log.error("Something went really wrong in ArrayUtils.convertArray method.", e);
        }

        // To satisfy the compiler
        return null;
    }

    /**
     * Convert any array of primitives(excluding char), strings or numbers into an array
     * of primitives(excluding char).
     *
     * @param array                       Array of primitives(excluding char), strings or numbers
     * @param convertedArrayComponentType Converted array component type primitive(excluding char)
     * @return Array of convertedArrayComponentType
     */
    public static Object convertToPrimitiveArray(Object array, Class convertedArrayComponentType) {

        // Collect data regarding arguments
        final boolean arrayOfPrimitives = isArrayOfPrimitives(array);
        final boolean arrayOfCharPrimitives = isArrayOf(array, char.class);
        final boolean arrayOfCharacters = isArrayOf(array, Character.class);
        final boolean arrayOfStrings = isArrayOf(array, String.class);
        final boolean arrayOfNumbers = isArrayOf(array, Number.class);

        // Check if array is an array of strings, primitives or wrapped primitives
        if (!arrayOfPrimitives && !arrayOfNumbers && !arrayOfStrings || arrayOfCharPrimitives || arrayOfCharacters) {
            throw new IllegalArgumentException(array + " must be an array of of strings, primitives or boxed primitives (byte, boolean, short, int, float, long, double)");
        }

        // Check if it's assignable from Number of String
        if (!convertedArrayComponentType.isPrimitive() || convertedArrayComponentType.isAssignableFrom(char.class)) {
            throw new IllegalArgumentException(convertedArrayComponentType + " must be a primitive(excluding char)");
        }

        try {
            return convertArrayInternal(array, convertedArrayComponentType);
        } catch (InvocationTargetException e) {

            // This can happen due to errors in conversion
            throw (RuntimeException) e.getTargetException();
        } catch (Exception e) {

            // This should never happen
            log.error("Something went really wrong in ArrayUtils.convertArray method.", e);
        }

        // To satisfy the compiler
        return null;
    }

    private static Object convertArrayInternal(Object array, Class convertedArrayComponentType) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        // Lookup the primitive parse method or the boxed primitive valueOf method
        final Method convertMethod;
        if (convertedArrayComponentType.isPrimitive()) {
            convertMethod = primitiveParseMethodLookup.get(convertedArrayComponentType);
        } else {
            convertMethod = valueOfMethodLookup.get(convertedArrayComponentType);
        }

        // If the array is an array of primitives lookup the get method
        final Method primitiveArrayGetMethod = primitiveArrayGetMethodLookup.get(array.getClass().getComponentType());

        // Get length and create new array
        final int arrayLength = Array.getLength(array);
        final Object castedArray = Array.newInstance(convertedArrayComponentType, arrayLength);

        for (int i = 0; i < arrayLength; i++) {

            final Object value;
            if (primitiveArrayGetMethod != null) {
                value = primitiveArrayGetMethod.invoke(null, array, i);
            } else {
                value = Array.get(array, i);
            }

            final String stringValue = String.valueOf(value);
            final Object castedValue = convertMethod.invoke(null, stringValue);
            Array.set(castedArray, i, castedValue);
        }

        return castedArray;
    }

}

It can be used like this:

String[] strings = new String[]{"1", "2", "3"};
Integer[] integers = ArrayUtils.convertArray(strings, Integer.class);
int[] ints = (int[]) ArrayUtils.convertToPrimitiveArray(strings, int.class);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM