I want to shift each elements in array to left if there is a null. E.g
public static void main(String[] args) {
String asd[] = new String[5];
asd[0] = "zero";
asd[1] = "one";
asd[2] = null;
asd[3] = "three";
asd[4] = "four;
I want the output to be
zero, one, three, four.
The length should also be adjusted
How can i do this using loops? I tried using if statements to check if an element is not null copy that value to another array. But i dont know how to copy if there is a null.
Given the kind of question, I suppose you want a simple, loop only and array only based solution, to understand how it works.
You have to iterate on the array, keeping an index of the new insertion point. At the end, using that same index, you can "shrink" the array (actually copy to a new smaller array).
String[] arr = {"a","b",null,"c",null,"d"};
// This will move all elements "up" when nulls are found
int p = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == null) continue;
arr[p] = arr[i];
p++;
}
// This will copy to a new smaller array
String[] newArr = new String[p];
System.arraycopy(arr,0,newArr,0,p);
Just tested this code.
EDIT :
Regarding the possibility of shrinking the array without using System.arraycopy, unfortunately in Java arrays size must be declared when they are instantiated, and can't be changed (nor made bigger nor smaller) after.
So if you have an array of length 6, and find 2 nulls, you have no way of shrinking it to a length of 4, if not creating a new empty array and then copying elements.
Lists can grow and shrink, and are more handy to use. For example, the same code with a list would be :
String[] arr = {"a","b",null,"c",null,"d"};
List<String> list = new ArrayList<>(Arrays.asList(arr));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) if (iter.next() == null) iter.remove();
System.out.println(list);
Try:
int lengthNoNull = 0;
for(String a : asd) {
if(a != null) {
lengthNoNull++;
}
}
String[] newAsd = new String[lengthNoNull];
int i = 0;
for(String a : asd) {
if(a != null) {
newAsd[i++] = a;
}
}
Piece of code using only arrays.
String[] x = {"1","2","3",null,"4","5","6",null,"7","8","9"};
String[] a = new String[x.length];
int i = 0;
for(String s : x) {
if(s != null) a[i++] = s;
}
String[] arr = Arrays.copyOf(a, i);
Or this:
String[] xx = {"1","2","3",null,"4","5","6",null,"7","8","9"};
int pos = 0, i = 0;
String tmp;
for(String s : xx) {
if(s == null) {
tmp = xx[pos];
xx[pos] = s;
xx[i] = tmp;
pos++;
}
i++;
}
String[] arr = Arrays.copyOfRange(xx, pos, xx.length);
Related
I have 2 string arrays.
string [] first = {"ajunkbc","ajunkHello","adedbc","abcjunk","add","ad","a","","junk","ajunk","aajunkbb"};
String [] second = {"abc","aHello","adedbc","abcjunk","add","ad","a","","junk","a","aajunkbb"};
I'd like the result of my merge() method to concatenate each element from the first array with the respective element of the second array separated by a comma.
Below is my code
private static String[] merge(String [] tests, String [] expectations){
List<String> testList = Arrays.asList(tests);
List<String> expectationsList = Arrays.asList(expectations);
List<String> retList = new ArrayList<String>();
for(String test : testList){
for(String val : expectationsList){
retList.add(test+","+val);
break;
}
}
This does not work. What's wrong with my code?
What's wrong is that you are looping over expectationsList and breaking out of the loop after the first iteration:
for(String val : expectationsList){
retList.add(test+","+val);
break; //<--- breaking out of loop after first iteration each time
}
So the result is that you are always retrieving the first element of expectationsList.
Since what you want is to loop over two arrays, you should use an index:
for (int i = 0; i < testList.size(); i++) {
retList.add(testList.get(i)+","+expectationsList.get(i));
}
Also, note that this implies that the size of testList is the same as the size of expectationsList. Your method should probably throw an exception if this is not the case.
Note that you do not need to convert the input arrays into lists. You can use them as-is.
private static String[] merge(String[] tests, String[] expectations) {
if (tests.length != expectations.length) {
throw new IllegalArgumentException("input not of same length");
}
String[] result = new String[tests.length];
for (int i = 0; i < tests.length; i++) {
result[i] = tests[i] + "," + expectations[i]);
}
return result;
}
Java 8 solution:
private static String[] merge(String[] tests, String[] expectations) {
if (tests.length != expectations.length) {
throw new IllegalArgumentException("input not of same length");
}
return IntStream.range(0, tests.length).mapToObj(i -> tests[i] + "," + expectations[i]).toArray(String[]::new);
}
You're iterating through each member of testList and then for each one, iterating through each member of expectationsList. You want to iterate through each of both of them together.
What you want to do is something like this:
private static String[] merge(String[] tests, String[] expectations) {
String[] result = new String[tests.length];
for(int i = 0; i < tests.length; i++) {
result[i] = tests[i] + "," + expectations[i];
}
return result;
}
This code makes the assumption that tests and expectations have the same length. You might want to do a check for that at the beginning:
if (tests.length != expectations.length) {
throw new IllegalArgumentException("tests and expectations are of different lengths")
}
Notice how now you're getting the element at the same index from both arrays.
Sidenote: You can iterate over arrays with the for each format. This works just fine:
String[] myStringArray = getStringArray();
for (String myString : myStringArray) {
// Do something
}
You don't need to convert to a List in order to iterate :)
Below are the 2 ways to remove null values, which one is the best approach?
public static String[] clean(final String[] v) {
List<String> list = new ArrayList<String>(Arrays.asList(v));
list.removeAll(Collections.singleton(null));
return list.toArray(new String[list.size()]);
}
public static String[] clean(final String[] v) {
List<String> list = new ArrayList<String>(v.length);
for (String aString : v)
{
if (aString != null)
{
list.add(aString);
}
}
return list.toArray(new String[list.size()]);
}
For removing null values from a single string, I would use a regular expression like this,
private static Pattern pattern = Pattern.compile("(?i)[(\\[{]?null[)\\]}]?");
public static String removeNullString(String value) {
if (StringUtils.isEmpty(value)) {
return StringUtils.EMPTY;
}
Matcher matcher = pattern.matcher(value);
return matcher.replaceAll(StringUtils.EMPTY);
}
It covers up all "null" and empty character from string.
For removing null value from a string array in Java 7,
String[] firstArray = {"test1", "", "test2", "test4", "", null};
List<String> list = new ArrayList<String>();
for(String s : firstArray) {
if(s != null && s.length() > 0) {
list.add(s);
}
}
firstArray = list.toArray(new String[list.size()]);
For removing null value from a string array in Java 8,
String[] firstArray = {"test1", "", "test2", "test4", "", null};
firstArray = Arrays.stream(firstArray)
.filter(s -> (s != null && s.length() > 0))
.toArray(String[]::new);
Performance wise, it is usually better to minimize calls outside of the scope of the current code block (ie method). Also, since memory allocation is relatively slow compared most other instructions, avoiding object creation is typically a goal. The best I can come up with in terms of performance (I chose to make it flexible enough to take any type of array):
public <T> T[] removeNulls(Class<T> type, final T[] original){
// first, shift all non-null instances to the head, all nulls to the end.
int nonNullCount=0;
T tempT = null;
for(int i=0; i < original.length; i++){
if(original[i] != null){
nonNullCount++;
}else if(i != original.length - 1){
// Swap the next non-null value with this null value
int j = i + 1;
// In case there are multiple null values in a row
// scan ahead until we find the next non-null value
while(j < original.length && (tempT = original[j]) == null){
j++;
}
original[nonNullCount] = tempT;
if(tempT != null){
nonNullCount++;
}
if(j < original.length){
original[j] = null;
}
i = j - 1;
}
}
// The case where there are no nulls in the array
if(nonNullCount == original.length){
return original;
}
final T[] noNulls = (T[]) Array.newInstance(type,nonNullCount);
System.arraycopy(original,0,noNulls,0,nonNullCount);
return noNulls;
}
But I'm not sure why you would want this complexity over the 3 or 4 lines to do the same thing when performance is not likely to be an issue. You would need to have HUGE arrays to see any benefit (if any) between my code and your clean example.
in Java 8 you should be able to do something like:
List<String> list = new ArrayList<String>(Arrays.asList(v));
list.removeIf(Objects::isNull);
return list.toArray(new String[list.size()]);
if you want to do it in same space i will suggest the follwing solution. But final array will also be having same size. I mean it will not shrink in size but all elements will get aggregated in same order.
public static void removeNullFromArray(String[] args) {
int location = 0;
for(int i=0; i<args.length; i++){
String arg = args[i];
if(arg!=null){
if(location<i){
args[location] = arg;
args[i] = null;
}
location++;
}
}
}
Java 8 code using streams and lambda. Filters non-nulls from an array and converts to a list.
Arrays.stream(arr).filter(Objects::nonNull).collect(Collectors.toList());
I am trying to populate a java string array with a variable. the variable contains values which I am reading in from a text file. every time a new value is stored in the array the current value is replaced by the new value.
the code below is what i have tried so far.
int n = 0;
String var1 = value;
String array[] = {var1};
String [] array = new String[n];
for (int i =0; i < n; i++) {
array[n++] = value;
}
Java has only fixed sized arrays; dynamically growing "arrays" are realized with List:
List<String> array = new ArrayList<>();
for (int i = 0; i < 42; ++i) {
String s = "" + i;
array.add(s);
}
for (String t : array) {
System.out.println(t);
}
String seven = array.get(7);
int n = array.size();
if (array.isEmpty()) { ... }
// In Java 8:
array.stream().sorted().forEach(System.out::println);
Using (fixed sized) arrays would be cumbersome:
String[] array = new String[];
String[] otherVar = array;
for (int i = 0; i < 42; ++i) {
String s = "" + i;
array = Arrays.copyOf(array, i + 1);
array[i] = s;
}
Here on every step a new array is created, the content of the old array copied.
Also notice that otherVar keeps the initial empty array.
Note that String[] a is the same as String a[]. The latter is only for compatibility to C/C++, and is less readable.
This will add a string indefinitely. When you read all the data from file you have to set isFileNotEnded = false
boolean isFileNotEnded = true;
List<String> array = new ArrayList<>;
while (isFileNotEnded) {
array.add("hello");
//stop here the infinite loop
}
This question already has answers here:
How to efficiently remove all null elements from a ArrayList or String Array?
(18 answers)
Closed 7 months ago.
I have following String Array
tmp = [null, null, null, Mars, Saturn, Mars] coming after doing the operation -
allSig[d3].split(" "); where allSig is an array of Strings. The null value is empty value in the array. Now I want to remove the null. For this I am using
tmp[indexNumber] != null is not working and giving true ; taking null as the value. Even if i am using "null" as a string is not working.
How to remove this.
public static String[] removeElements(String[] allElements) {
String[] _localAllElements = new String[allElements.length];
for (int i = 0; i < allElements.length; i++)
if (allElements[i] != null)
_localAllElements[i] = allElements[i];
return _localAllElements;
}
public static String[] clean(final String[] v) {
int r, w;
final int n = r = w = v.length;
while (r > 0) {
final String s = v[--r];
if (!s.equals("null")) {
v[--w] = s;
}
}
return Arrays.copyOfRange(v, w, n);
}
or
public static String[] clean(final String[] v) {
int r, w, n = r = w = v.length;
while (r > 0) {
final String s = v[--r];
if (!s.equals("null")) {
v[--w] = s;
}
}
final String[] c = new String[n -= w];
System.arraycopy(v, w, c, 0, n);
return c;
}
Works fine...
public static void main(final String[] argv) {
final String[] source = new String[] { "Mars", "null", "Saturn", "null", "Mars" };
assert Arrays.equals(clean(source), new String[] { "Mars", "Saturn", "Mars" });
}
You're creating an array with same size as the original one. So it's the same as the original array, as you copy non null values and default values are null.
Do this :
public static String[] removeElements(String[] allElements) {
// 1 : count
int n = 0;
for (int i = 0; i < allElements.length; i++)
if (allElements[i] != null) n++;
// 2 : allocate new array
String[] _localAllElements = new String[n];
// 3 : copy not null elements
int j = 0;
for (int i = 0; i < allElements.length; i++)
if (allElements[i] != null)
_localAllElements[j++] = allElements[i];
return _localAllElements;
}
Abstracting #az answer, this applies to any class type:
#SuppressWarnings("unchecked")
public static <T> T[] clean(T[] a) {
List<T> list = new ArrayList<T>(Arrays.asList(a));
list.removeAll(Collections.singleton(null));
return list.toArray((T[]) Array.newInstance(a.getClass().getComponentType(), list.size()));
}
If you want the array to contain only the non-null values (i.e. the resulting array would be ["Mars", "Saturn", "Mars"]), then I would look at this as a two part problem.
First, you must identify what the size of the new array should be. From inspection, it's easy to see that it's 3, but you will need to need to count them to calculate this programmatically. You can do this by saying:
// Calculate the size for the new array.
int newSize = 0;
for (int i = 0; i < allElements.length; i++) {
if (allElements[i] != null) {
newSize++;
}
}
Secondly, you will need to create a new array with that size. Then you can put all of the non-null elements into your new array, as you have done above.
// Populate the new array.
String[] _localAllElements = new String[newSize];
int newIndex = 0;
for (int i = 0; i < allElements.length; i++) {
if (allElements[i] != null) {
_localAllElements[newIndex] = allElements[i];
newIndex++;
}
}
// Return the new array.
return _localAllElements;
You can just combine these two components as the new content of your results method. See the full combined code and live sample output here.
public static String[] removeElements(String[] allElements) {
String[] _localAllElements = new String[allElements.length];
int j = 0;
for (int i = 0; i < allElements.length; i++)
if ( allElements[i] != null && !allElements[i].equals(""))
_localAllElements[j++] = allElements[i];
return _localAllElements;
}
This is a very old question but this Java 8+ solution might be useful to someone:
public static String[] removeElements(String[] allElements) {
return Arrays.stream(allElements)
.filter(Objects::nonNull)
.collect(Collectors.toArray());
}
or if you, like me, are a fan of readable code and don't want static methods to get in your way, you can simplify this even further using static imports:
public static String[] removeElements(String[] allElements) {
return stream(allElements).filter(Objects::nonNull).collect(toArray());
}
I want to eliminate empty elements within my String array. This is what I have tried so far:
String version = null;
String[] xml = new String[str.length];
for(int i = 0; i <= str.length -1; i++)
{
if(str[i] == "")
{
}
else
{
xml[i] = str[i];
}
}
String version = null;
String[] xml = new String[str.length];
for(int i = 0; i <= str.length -1; i++)
{
if(!str[i].equals(""))
{
xml[i] = str[i];
}
}
String version = null;
String[] xml = new String[str.length];
for(int i = 0; i <= str.length -1; i++)
{
if(!str[i].isEmpty())
{
xml[i] = str[i];
}
}
String version = null;
String[] xml = new String[str.length];
for(int i = 0; i <= str.length -1; i++)
{
if(str[i].isEmpty() == false)
{
xml[i] = str[i];
}
}
No matter which one I try, it always copies all the values. I've checked the locals, and it is clear that there are empty arrays within the String array.
Try this,
b = Arrays.copyOf(a, a.length);
Or
b = new int[a.length];
System.arraycopy(a, 0, b, 0, b.length);
Or
b = a.clone();
You are copying the same length array and using the same indexes. The length is always going to be the same.
List<String> nonBlank = new ArrayList<String>();
for(String s: str) {
if (!s.trim().isEmpty()) {
nonBlank.add(s);
}
}
// nonBlank will have all the elements which contain some characters.
String[] strArr = (String[]) nonBlank.toArray( new String[nonBlank.size()] );
String str[] = {"Hello","Hi","","","Happy","","Hmm"};
int count = 0;// Thisreprents the number of empty strings in the array str
String[] xml = new String[str.length];
for(int i = 0,j=0; i <= str.length -1; i++)
{
if(str[i].equals(""))
{
count++;
}
else
{
xml[j] = str[i];j++;
}
}
String a[] = Arrays.copyOfRange(xml, 0, xml.length-count);//s is the target array made by copieng the non-null values of xml
for(String s:a){
System.out.println(s);
}
NOTE : This may not be an efficient solution but it will give the result as per your requirement
This is just an alternate solution since you didn't want ListArray.
Read the comments in the code to clearly understand the logic.
int i,j=0,cnt=0;
//The below for loop is used to calculate the length of the xml array which
//shouldn't have any empty strings.
for(i=0;i<str.length;i++)
if(!isEmpty(str[i])
cnt++;
//Creation of the xml array with proper size(cnt) and initialising i=0 for further use
String xml[]=new String[cnt];
i=0;
//Simply copying into the xml array if str[i] is not empty.Notice xml[j] not xml[i]
while(i<str.length)
{
if(!isEmpty(str[i]))
{
xml[j]=str[i];
i++;
j++;
}
else
i++;
}
That should do the work.
Also I would suggest to not work with the 0th position of array as it kinda creates confusion for .length functions.Thats only my view. If you are comfortable with it,carry on! :D
If you are looking for a high-performance solution I think that this is the best solution. Otherwise if your input array is not so huge, I would use a solution similar to Peter Lawrey one, so it makes your code easy to understand.
With this solution you loop the input array only one, and if you don't need the input array any more you can avoid one array copy calling filterBlankLines with preserveInput = false.
public class CopyingStringArrayIntoNewStringArray {
public static void main(String[] args) {
String[] str = { "", "1", "", null, "2", " ", "3", "" };
System.out.println("\nBefore:");
printArrays(str);
String[] xml = filterBlankLines(str, true);
System.out.println("\nAfter:");
printArrays(xml);
}
private static String[] filterBlankLines(String input[], boolean preserveInput ) {
String[] str;
if (preserveInput) {
str = new String[input.length];
System.arraycopy(input, 0, str, 0, input.length);
} else {
str = input;
}
// Filter values null, empty or with blank spaces
int p=0, i=0;
for (; i < str.length; i++, p++) {
str[p] = str[i];
if (str[i] == null || str[i].isEmpty() || (str[i].startsWith(" ") && str[i].trim().isEmpty())) p--;
}
// Resize the array
String[] tmp = new String[ p ];
System.arraycopy(str, 0, tmp, 0, p);
str = null;
return tmp;
}
private static void printArrays(String str[]) {
System.out.println( "length " + str.length);
for (String s : str ) {
System.out.println(">"+s+"<");
}
}
}
The output:
Before:
length 8
><
>1<
><
>null<
>2<
> <
>3<
><
After:
length 3
>1<
>2<
>3<
This is the best and short way to copy an array into the new array.
System.arraycopy(srcArray, 0, destArray, 1, destArray.length -1);