How would I iterate through an array and attempt to convert a string to a long? This is an example below:
String[] myArray = ["123", "122 Street", "2334"];
// I'm trying to loop through an array like this and cast to a long
for(String s: myArray) {
try {
long newValue = Long.valueOf(s);
// How would I swap the old values to their new long type in the
// myArray?
} catch(Exception error) { }
}
You cannot put a long into a String[]. You'd need to create a second array specifically for holding the longs. I'm unsure whether "122 Street" would cast correctly or give an error.
String[] myArray = ["123", "122 Street", "2334"];
long[] longs = new long[myArray.length];
for (int i = 0; i < myArray.length; i++) {
try {
longs[i] = Long.valueOf(myArray[i]);
} catch (Exception e) {
// Handle error case
}
}
Java arrays only store the type they were declared to store (Java ain't JavaScript).
Here's a 1-liner:
long[] numbers = Arrays.stream(myArray)
.filter(s -> s.matches("\\d+"))
.mapToLong(Long::parseLong)
.toArray();
before converting a string to long, I'd validate that it has only digits in order to avoid exceptions which are very costly in Java (unlike other languages such as Python in which raising and catching exceptions is perfectly normal).
Since we have no way of knowing what will be the size of the new array, and having array that contains nulls is not ideal, we can work with a List to collect the results and when we're done - convert it into an array of Long
public static void main(String[] args) {
String[] myArray = {"123", "122 Street", "2334"};
Long[] array = stringsToLongs(myArray);
}
private static Long[] stringsToLongs(String[] myArray) {
List<Long> list = new LinkedList<>();
for(String s: myArray) {
if (s.matches("\\d+"))
list.add(Long.valueOf(s));
}
return list.toArray(new Long[list.size()]);
}
How would I swap the old values to their new long type in the myArray?
You wouldn't. Your array is already of Type of string. It can only accept string values. If you want an equivalent array of type long, you will need exactly that. A different array, of that type; with equivalent values stored inside.
Other answers are not technically correct in their current wording. One can put a long value in a string[] array; just not in a long type/format.
The same applies in reverse (which is what you seem to want to do): You can have long[] holding data that was previously in string type/format. You just need to do the proper conversion.
Another thing other answers get slightly wrong, is that there is technically no casting, in the true meaning of the word, between numerical types and strings. What is done instead is called parsing.
In the case of your issue specifically, parsing a long value from it's string representation is done using long.valueOf(string s).
Note that this method expects a string representation of a number, and will fail with NumberFormatException with something else.
This includes "122 Street". That's not a number. "122" is. So you'll have to parse "122" out of the rest of the string first, before converting that to long.
Solution:
String[] myArray = ["123", "122 Street", "2334"];
myArray[1] = myArray[1].substring(0,2); //Removes " Street" from second element.
long[] myLongs = new long[myArray.length];
for(int i=0; i<myArray.length; i++) {
try {
myLongs[i] = Long.valueOf(myArray[i]);
} catch(NumberFormatException nfe) {
System.out.println("Element at index "+i+" could not be parsed.");
} catch(Exception ex) {
System.out.println("Some other exception happened.");
}
}
Related
I have the following code which sorts a mixed array of items while maintaining the position of types:
For example:
[20, "abc", "moose", 2,1] turns into [1, "abc", "moose", 2, 20]
Algorithm:
public class Algorithm {
public static String[] sortMixedArray(String[] input){
if (input.length == 0){
return input;
}
// make new arraylist for strings and numbers respectively
List<String> strs = new ArrayList<String>();
List<Integer> numbers = new ArrayList<Integer>();
// add values to the arraylist they belong to
for (String item : input){
if (NumberUtils.isNumber(item)){
numbers.add(Integer.valueOf(item));
} else {
strs.add(item);
}
}
// sort for O(nlogn)
Collections.sort(strs);
Collections.sort(numbers);
// reuse original array
for (int i = 0; i < input.length; i++){
if (NumberUtils.isNumber(input[i])) {
input[i] = String.valueOf(numbers.remove(0));
} else {
input[i] = strs.remove(0);
}
}
return input;
}
public static void main(String[] args) {
String[] test = new String[] {"moo", "boo"};
System.out.println(Arrays.toString(sortMixedArray(test)));
}
I have a two-part question:
1. Is switching between array and arraylist efficient? That is, should I have used arrays everywhere instead of arraylist if my input MUST be an array.
2. What is the best way to place arraylist items back into a array? I am checking for type, is there a better way?
1.If you do it the way you have it in your code then it's perfectly fine. If you know beforehand how many elements you will have it's better to use arrays but thats not the case in your example.
2.The best and easiest way is to use the toArray() function of the List interface.
ArrayList<String> list = ...;
String[] array = list.toArray(new String[list.size()]);
But this won't work for your code since you are merging two lists into one array. You can still improve your code a bit because you do not actually have to remove the items from the lists when putting them back in the array. This safes some computation since removing the first element from an ArrayList is very inefficient (O(N) runtime per remove operation).
for (int i = 0, s = 0, n = 0; i < input.length; i++) {
if (NumberUtils.isNumber(input[i])) {
input[i] = Integer.toString(numbers.get(n++));
} else {
input[i] = strs.get(s++);
}
}
No but it highly unlikely to matter unless you have a million of elements.
Do whatever you believe is simplest and most efficient for you, the developer.
BTW the least efficient operations is remove(0) which is O(N) so you might change that.
After parsing my file " s" contains AttributeGet:1,16,10106,10111
So I need to get all the numbers after colon in the attributeIDGet List. I know there are several ways to do it. But is there any way we can Directly convert List<String> to List<Integer>.
As the below code complains about Type mismatch, so I tried to do the Integer.parseInt, but I guess this will not work for List. Here s is String.
private static List<Integer> attributeIDGet = new ArrayList<Integer>();
if(s.contains("AttributeGet:")) {
attributeIDGet = Arrays.asList(s.split(":")[1].split(","));
}
Using Java8:
stringList.stream().map(Integer::parseInt).collect(Collectors.toList());
No, you need to loop over the array
for(String s : strList) intList.add(Integer.valueOf(s));
Using lambda:
strList.stream().map(org.apache.commons.lang3.math.NumberUtils::toInt).collect(Collectors.toList());
You can use the Lambda functions of Java 8 to achieve this without looping
String string = "1, 2, 3, 4";
List<Integer> list = Arrays.asList(string.split(",")).stream().map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList());
Guava Converters do the trick.
import com.google.common.base.Splitter;
import com.google.common.primitives.Longs;
final Iterable<Long> longIds =
Longs.stringConverter().convertAll(
Splitter.on(',').trimResults().omitEmptyStrings()
.splitToList("1,2,3"));
No, you will have to iterate over each element:
for(String number : numbers) {
numberList.add(Integer.parseInt(number));
}
The reason this happens is that there is no straightforward way to convert a list of one type into any other type. Some conversions are not possible, or need to be done in a specific way. Essentially the conversion depends on the objects involved and the context of the conversion so there is no "one size fits all" solution. For example, what if you had a Car object and a Person object. You can't convert a List<Car> into a List<Person> directly since it doesn't really make sense.
If you use Google Guava library this is what you can do, see Lists#transform
String s = "AttributeGet:1,16,10106,10111";
List<Integer> attributeIDGet = new ArrayList<Integer>();
if(s.contains("AttributeGet:")) {
List<String> attributeIDGetS = Arrays.asList(s.split(":")[1].split(","));
attributeIDGet =
Lists.transform(attributeIDGetS, new Function<String, Integer>() {
public Integer apply(String e) {
return Integer.parseInt(e);
};
});
}
Yep, agree with above answer that's it's bloated, but stylish. But it's just another way.
Why don't you use stream to convert List of Strings to List of integers?
like below
List<String> stringList = new ArrayList<String>(Arrays.asList("10", "30", "40",
"50", "60", "70"));
List<Integer> integerList = stringList.stream()
.map(Integer::valueOf).collect(Collectors.toList());
complete operation could be something like this
String s = "AttributeGet:1,16,10106,10111";
List<Integer> integerList = (s.startsWith("AttributeGet:")) ?
Arrays.asList(s.replace("AttributeGet:", "").split(","))
.stream().map(Integer::valueOf).collect(Collectors.toList())
: new ArrayList<Integer>();
If you're allowed to use lambdas from Java 8, you can use the following code sample.
final String text = "1:2:3:4:5";
final List<Integer> list = Arrays.asList(text.split(":")).stream()
.map(s -> Integer.parseInt(s))
.collect(Collectors.toList());
System.out.println(list);
No use of external libraries. Plain old new Java!
Using Streams and Lambda:
newIntegerlist = listName.stream().map(x->
Integer.valueOf(x)).collect(Collectors.toList());
The above line of code will convert the List of type List<String> to List<Integer>.
I hope it was helpful.
No, there is no way (that I know of), of doing that in Java.
Basically you'll have to transform each entry from String to Integer.
What you're looking for could be achieved in a more functional language, where you could pass a transformation function and apply it to every element of the list... but such is not possible (it would still apply to every element in the list).
Overkill:
You can, however use a Function from Google Guava (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Function.html) to simulate a more functional approach, if that is what you're looking for.
If you're worried about iterating over the list twice, then instead of split use a Tokenizer and transform each integer token to Integer before adding to the list.
Here is another example to show power of Guava. Although, this is not the way I write code, I wanted to pack it all together to show what kind of functional programming Guava provides for Java.
Function<String, Integer> strToInt=new Function<String, Integer>() {
public Integer apply(String e) {
return Integer.parseInt(e);
}
};
String s = "AttributeGet:1,16,10106,10111";
List<Integer> attributeIDGet =(s.contains("AttributeGet:"))?
FluentIterable
.from(Iterables.skip(Splitter.on(CharMatcher.anyOf(";,")).split(s)), 1))
.transform(strToInt)
.toImmutableList():
new ArrayList<Integer>();
Use Guava transform method as below,
List intList = Lists.transform(stringList, Integer::parseInt);
import java.util.Arrays;
import java.util.Scanner;
public class reto1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double suma = 0, promedio = 0;
String IRCA = "";
int long_vector = Integer.parseInt(input.nextLine());
int[] Lista_Entero = new int[long_vector]; // INSTANCE INTEGER LIST
String[] lista_string = new String[long_vector]; // INSTANCE STRING LIST
Double[] lista_double = new Double[long_vector];
lista_string = input.nextLine().split(" "); // INPUT STRING LIST
input.close();
for (int i = 0; i < long_vector; i++) {
Lista_Entero[i] = Integer.parseInt(lista_string[i]); // CONVERT INDEX TO INDEX FROM STRING UNTIL INTEGER AND ASSIGNED TO NEW INTEGER LIST
suma = suma + Lista_Entero[i];
}
I want to decompose a String array into Long array or List.
I don't want to use Loop.
Is there any Java Method to do this.
Simplified Eugene answer with Guava library. Since Guava 16.0.
List<Long> longList = Lists.transform(Arrays.asList(stringArray), Longs.stringConverter());
Update: Solution with Java 8, without 3th party libraries:
List<Long> longList = Stream.of(stringArray).map(Long::valueOf).collect(Collectors.toList());
There is no O(1) operation to "convert" a String[] (with numeric strings) to a long[]. It will always be O(n), if the loop visible or hidden in some thirdparty method.
If you don't want to "see" the loop, simply implement a method
Long[] pseudoOneStepConversion(numbers);
and implement
privat Long[] pseudoOneStepConversion(String[] numbers) {
Long[] result = new long[numbers.length];
for (int i = 0; i < numbers.length; i++)
result[i] = Long.parseLong(numbers[i]);
return result;
}
We can do it recursively too - it is still O(n), less performant and doesn't look like a loop:
public static void main(String[] args) {
List<Long> target = new ArrayList<Long>();
copy(new String[]{"1", "2", "3"}, target, 0);
System.out.println(target);
}
private static void copy(String[] source, List<Long> target, int index) {
if (index == source.length)
return;
target.add(Long.parseLong(source[index]));
copy(source, target, index+1);
}
Note - because I start getting downvotes for the recursion example: It is purely academic and not inteded for use in production code - thought, that was clear ;)
With a little help of 3rd party libraries you can avoid coding loops in your own code, but there would be a loop somewhere under the hood. For example:
List<String> stringList = Arrays.asList(stringArray);
List<Long> longList = Lists.transform(stringList, new Function<String, Long>() {
public Long apply(String s) {
return Long.valueOf(s);
}
});
Classes Lists and Function are from Guava library.
No there is no way to do this without a loop (even if you don't code explicitly a loop, the method you will call will use one), unless you now the number of long values contained in the String and add them manually to your List.
Your best option is Guavas Lists.transform function.
String[] stringArray = {"1999", "20000"};
List<String> stringList = Arrays.asList(stringArray);
List<Long> longList = Lists.transform(stringList,
new Function<String, Long>() {
Long apply(String value) {
return Long.valueOf(value);
}
});
Note: Guava will of course have to do a loop to achieve this, but there are no loops in your code.
Split String value with comma and Converting String Array to Wrapper Long Array / Primitive long array using Java 8.
String values = "2846, 4514, 8495, 4587, 5772, 3813, 6947, 3186";
Long[] longArray = Arrays.stream(values.split(","))
.map(String::trim)
.map(Long::valueOf)
.toArray(Long[]::new);//Converting String array to Long array
long[] longPrimitiveArray = Arrays.stream(values.split(","))
.map(String::trim)
.mapToLong(Long::valueOf)
.toArray();//Converting String array to long array
I have a method return type as ArrayList<String> which is also reading an argument of the same type. Now how do I type cast or modify my BigDecimal to read that value?
public static ArrayList<String> currencyUtilArray(ArrayList<String> amountStr ) {
BigDecimal amount = new BigDecimal(ArrayList<String> amountStr);
//How do I define that the amountStr is ArrayList<String> and need to place in BigDecimal amount one after another till the end of the List
return amountStr;
}
Or do I need to do
You can't type cast a String to a BigDecimal or vice versa.
If the strings in the array are meant to represent a number when concatenated then do something like this:
StringBuilder sb = new StringBuilder();
for (String s : amountStr) {
sb.append(s);
}
BigDecimal amount = new BigDecimal(sb.toString());
On the other hand, if each String represents a distinct number:
for (String s : amountStr) {
BigDecimal amount = new BigDecimal(s);
// ... and do something with it ...
}
I don't think you are referencing it correctly. You can't convert the whole ArrayList as an AL of type string to a Big Decimal.
First, change the ArrayList amountStr from within the new BigDecimal(--); and reference a single String from within the ArrayList.
Meaning you would have to loop through the whole thing, adding it into amount:
BigDecimal amount = new BigDecimal(amountStr.get(0));
For(int i = 1; i < amountStr.size(); i++){
amount = amount.add(new BigDecimal(amountStr.get(i)));
}
I believe that should give you what you need when it is returned.
what i understand is you want to convert the list elements into BigDecimal Array. If so you can do as below:
BigDecimal[] amount = new BigDecimal[amountStr.size()];
for (int i=0;i<amountStr.size();i++) {
amount[i] = new BigDecimal(amountStr.get(i));
}
I'm in need of help right now. I need to convert 2 dimensional array of numbers to a one dimensional array in Java. Can anyone help me?
Do you mean something like this?
import java.util.*;
public class Test {
public static void main(String[] args) {
String[][] data = new String[][] {
{ "Foo", "Bar" },
{ "A", "B" }
};
String[] flattened = flatten(data);
for (String x : flattened) {
System.out.println(x);
}
}
public static <T> T[] flatten(T[][] source) {
int size = 0;
for (int i=0; i < source.length; i++) {
size += source[i].length;
}
// Use the first subarray to create the new big one
T[] ret = Arrays.copyOf(source[0], size);
int index = source[0].length;
for (int i=1; i < source.length; i++) {
System.arraycopy(source[i], 0, ret, index, source[i].length);
index += source[i].length;
}
return ret;
}
}
If you want it for primitive types, you'll have to write an overload for each primitive type, but you can use new int[size] instead of Arrays.copyOf at that point.
A Java 8 solution could look something like this:
import java.util.stream.Stream;
public class ArrayConverter {
public static String[] flatten(String[][] array) {
// Create a stream of the given array
return Stream.of(array)
// Map each of its elements to a stream (thus creating a
// one-dim-array inside the stream, so to say)
.flatMap(Stream::of)
// Retrieve the stream as array, explicitly calling String to
// keep the type
.toArray(size -> new String[size]);
}
}
I consciously left out generic types in this example since it makes the Array Initialization somewhat confusing. Let me know if you need it tho.
Notably; if you want to use this conversion for Arrays of primitive types you should use the corresponding flat Methods of the Stream Class.
E.g. if you're using int-Arrays use:
Stream.flatMapToInt(...)
to retrieve an IntStream with actual primitive int-Values thus dodging autoboxing into Integer Objects.
JavaDoc of Stream for reference