How to remove null from an array in java - java

I've written a method to remove null-values from an array i need in a program.
The method, however, doesn't seem to work, the null values won't go away. This is my code so far.
public void removeNull(String[] a)
{
for(int i=0; i<a.length; i++)
{
if(a[i] == null)
{
fillArray(a, i);
}
}
}
public void fillArray(String[] a, int i)
{
String[] a2 = new String[a.length-1];
for(int j=0; j<a2.length; j++)
{
if(j<i)
{
a2[j]=a[j];
}
else if(j>i)
{
a2[j]=a[j+1];
}
}
a=a2;
}
Thanks in advance!

I would advocate doing it the simple way unless performance is really a problem:
public String[] removeNull(String[] a) {
ArrayList<String> removedNull = new ArrayList<String>();
for (String str : a)
if (str != null)
removedNull.add(str);
return removedNull.toArray(new String[0]);
}

Streams API version of the solution:
SomeClass[] array = new SomeClass[N];
...
array = Arrays.stream(array).filter(Objects::nonNull).toArray(SomeClass[]::new);
(I post this down to maybe get some thoughts on applicability, relative performance etc)

hi everyone first of all i want to appologize for my english im learning at this moment and this is my first post so i want to try to put my solution about the problem here it is
String[] removeNulls(String[] nullsArray) {
int countNulls = 0;
for (int i = 0; i < nullsArray.length; i++) { // count nulls in array
if (nullsArray[i] == null) {
countNulls++;
}
}
// creating new array with new length (length of first array - counted nulls)
String[] nullsRemoved = new String[nullsArray.length - countNulls];
for (int i = 0, j = 0; i < nullsArray.length; i++) {
if (nullsArray[i] != null) {
nullsRemoved[j] = nullsArray[i];
j++;
}
}
return nullsRemoved;
}

You can't change the reference to a variable in a method and expect it to be reflected in the calling method.
You'll instead have to return the new array.
public String[] removeNull(String[] a)
{
for(int i=0; i<a.length; i++)
{
if(a[i] == null)
{
a = fillArray(a, i);
}
}
return a;
}
public String[] fillArray(String[] a, int i)
{
String[] a2 = new String[a.length-1];
for(int j=0; j<a2.length; j++)
{
if(j<i)
{
a2[j]=a[j];
}
else if(j>i)
{
a2[j]=a[j+1];
}
}
return a2;
}

This way would be faster:
private static String[] removeNulls(String[] strs) {
int i = 0;
int j = strs.length - 1;
while (i <= j) {
if (strs[j] == null) {
--j;
} else if (strs[i] != null) {
++i;
} else {
strs[i] = strs[j];
strs[j] = null;
++i; --j;
}
}
return Arrays.copyOfRange(strs, 0, i);
}

I can see two errors in your code:
Your method fillArray doesn't cover the case i == j
Your assignation a = a2; doesn't have the effect you think it might have. Arguments are passed by value in Java, and your assignment does NOT change the value of a in your first method. Try returning an instance to a2 in fillArray, and assign this value to a in removeNull.

A couple of things:
Don't you wantString[] a2 = new String[a.length-1];` to be
String[] a2 = new String[a.length];
Won't making it length - 1 make it too short?
You need a case for i == j in your code. This is why the nulls aren't getting updated.
What problem are you trying to solve with the second function? It seems complicated given what I thought your problem was.

Try this (I didn't test it):
public String[] removeNull(String[] a) {
String[] tmp = new String[a.length];
int counter = 0;
for (String s : a) {
if (s != null) {
tmp[counter++] = s;
}
}
String[] ret = new String[counter];
System.arraycopy(tmp, 0, ret, 0, counter);
return ret;
}

This way you can remove nulls in one cycle, but it will not resize array:
public static void removeNull(String[] a) {
int nullCount = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] == null) {
nullCount++;
} else {
a[i-nullCount] = a[i];
}
}
}
This one creates new array, but includes two cycles:
public static String[] removeNull(String[] a) {
int nullCount = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] == null) nullCount++;
}
String[] b = new String[a.length-nullCount];
int j = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] != null) b[j++] = a[i];
}
return b;
}
You can think on optimizing that code using System.arraycopy. I hope the code works.

When removing values in an array, the size changes so you can't keep the same array (you could push the nulls at the end).
The structure close to an array that has a auto-adjustable size is an ArrayList. One option would be :
String[] inputs;
List<String> items = new ArrayList<String>(inputs.length);
for(String input : inputs) {
if (input != null) {
items.add(input);
}
}
String[] outputs = items.toArray(new String[items.size()]);
Performance might be a bit less than working directly with arrays, but because an array has a fixed size, you would need two loops with arrays :
one to count the number of non-null values
after building the array, the same loop to copy the values.
This might not have an ideal performance either, and it is really much more complex to get it right...
Another approach would be to move the nulls at the end, then create a shorter array that wouldn't include the nulls. The idea would be :
String[] strings;
int writeIndex = 0;
int max = strings.length;
for(int readIndex = 0; readIndex < max; readIndex++) {
String read = strings[readIndex];
if (read != null) {
strings[writeIndex++] = read;
}
}
String[] outputs = new String[writeIndex];
System.arraycopy(strings, 0, ouputs, 0, writeIndex);

Well, more people said it before... but I also want to emphasize this solution:
You can use some type of Collection, like ArrayList or List and add only the not null elements. Finally you must return the new String[] formed by the Collection.
Here an example where you can check the correctness:
import java.util.ArrayList;
public class NullRemove {
public static String[] removeNull(String[] a) {
ArrayList<String> aux = new ArrayList<String>();
for (String elem : a) {
if (elem != null) {
aux.add(elem);
}
}
return (String[]) aux.toArray(new String[aux.size()]);
}
public static void main(String[] args) {
String[] init = new String[]{"aaa", null, "bbb", "ccc", null, "ddd",
"eee", "fff", null};
String[] result = NullRemove.removeNull(init);
System.out.println("Start Check result");
for (String elem : result) {
if (elem == null) System.out.println("NULL element");
}
System.out.println("End Check result");
}
}
The for with the code don't print anything cause there is any null element :)
Regards!

You have two options:
Create new array that length is same as the input, then assign to it not null values and add the substract it to the count of not null elememts .
Example in 0xJoKe answer.
If You need to work only sutch array you could create an adapter for it.
public class NullProofIterable<T> implements Iterable<T>{
private final T[] array;
public NullProofIterable(T[] array){
this.array = array;
}
#Override
public Iterator<T> iterator() {
return new NullProofIterator<T>(this.array);
}
private static class NullProofIterator<T> implements Iterator<T> {
private final T[] array;
private final int index = 0;
private NullProofIterator(T[] array) {
this.array = array;
}
#Override
public boolean hasNext() {
return this.index < this.array.length;
}
#Override
public T next() {
return this.array[this.index];
}
#Override
public void remove() {
throw new RuntimeException("Remove not allowed in this iterator");
}
}
}
Then in source code, only thing you have to do is:
for(String str : new NullProofIterable<String>(strArray)) {
//Perform action on not null string
}
The second option is very fancy usage of != null condition bu it might be helful when a method need to return some data.

Related

Am I comparing strings lexicographically correctly?

I am creating a method compareTo(AltString altStr2) that sorts strings by their length (shortest to longest).
However, I would like to go the extra mile and check for strings that are of the same length. In that case, I figure it is best to sort the strings lexicographically, so that they are sorted in the same way they would appear in the dictionary. So far my code is below.
public class AltString {
String internalStr;
public AltString(String str) {
internalStr = str;
}
public String toString() {
return internalStr;
}
public int compareTo(AltString altStr2) {
if (this.internalStr.length() < altStr2.internalStr.length()) {
return -1;
} else if (this.internalStr.length() > altStr2.internalStr.length()) {
return 1;
} else {
int idx = 0;
while (this.internalStr.charAt(idx) != altStr2.internalStr.charAt(idx)) {
if (this.internalStr.charAt(idx) < altStr2.internalStr.charAt(idx)) {
return -1;
}else if (this.internalStr.charAt(idx) > altStr2.internalStr.charAt(idx)) {
return 1;
} else {
idx += 1;
public static void main(String[] args) {
// some test code for the AltString class
String [] list = {"fortran", "java", "perl", "python", "php", "javascrip", "c", "c++", "c#", "ruby"};
AltString [] alist = new AltString[list.length];
for (int i=0; i<alist.length; i++) {
alist[i] = new AltString(list[i]);
}
Arrays.sort(list);
Arrays.sort(alist);
System.out.println("String sort:");
for (int i=0; i<list.length; i++) {
System.out.println(list[i]);
}
System.out.println("\nAltString sort:");
for (int i=0; i<alist.length; i++) {
System.out.println(alist[i]);
}
}
The part I am must stuck on is comparing the strings lexicographically. Currently, I have my code setup so that I enter a while-loop and compare each char.
My question is, is this the most efficient way to do this, or is there a better way to compare each string lexicographically in the cases where the strings are the same length?
Following the suggestions of Tunaki and JB Nizet, you can use Integer.compare and String.compareTo. Using String.compareTo does not count as recursion. Recursion is when you call a method from itself, but String.compareTo is a different method from AltString.compareTo.
public int compareTo(AltString altStr2) {
int temp = Integer.compare(this.internalStr.length(), altStr2.internalStr.length());
return temp != 0 ? temp : this.internalStr.compareTo(altStr2.internalStr);
}

To remove the duplicate words from the array and returning the unique to the same array

I was trying to remove the duplicates from the list of arrays, I was trying to use simple for loop instead of hashset..
Can anyone suggest how can I improve my program:
public class removeduplicates {
public static void main(String[] args) {
String[] words={"Others","Others","Others","Sentence"};
String output=words[0];
int count=0;
for(int i=0;i<words.length-1;i++) {
for(int j=i+1;j<words.length;j++) {
if(words[i].equals(words[j])) {
count++;
}
else {
output=output+words[j];
}
}
i=count;
}
System.out.println(output);
}
}
In this program if we give input as Others, Sentence, Others, Sentence then I am not getting the required output: I need just Others and Sentence as output...
If possible I have a condition that when I am entering words array, I need the output array with only unique values in the same array words.
String [] input={"other", "other","sentence","other"};
String current=input[0];
boolean found=false;
for(int i=0; i<input.length; i++){
if (current == input[i] && !found) {
found = true;
} else if (current != input[i]) {
System.out.print(" " + current);
current = input[i];
found = false;
}
}
I suggest to use collections as you can't resize an array
ArrayList<String> noDuplicateList = new ArrayList<>();
String[] words={"Others","Others","Others","Sentence"};
for(int i=0;i<words.length;i++) {
if(!noDuplicateList.contains(words[i])){
noDuplicateList.add(words[i]);
}
}
Here's a link
The simplest way to solve the duplication is declared already using HashSet, Anyway look at this code using loop:
Step 1: replace duplicate value with null
String[] words={"Others","B","Sentence","A","Others","A","Sentence"};
for(int i=0; i < words.length ;i++) {
String toBeRemoved = words[i];
for(int j=i+1 ; j < words.length; j++) {
if(words[j] != null && words[j].equals(toBeRemoved)) {
words[i] = null;
}
}
}
Now if you print the words values then the output will be:
System.out.println(Arrays.asList(words));
output: [null, B, null, null, Others, A, Sentence]
Step 2: Remove the null values (there are many ways to do it) for example:
List<String> list = new ArrayList<>(Arrays.asList(words));
list.removeIf(new Predicate<String>() {
#Override
public boolean test(String t) {
return (t == null || t.length() < 0);
}
});
words = list.toArray(new String[0]);
Using lambda JDK 8:
words = Arrays.stream(words).filter(t -> (t != null && t.length() > 0)).toArray(String[]::new);
Now if you print the words values then the output will be:
System.out.println(Arrays.asList(words));
output: [B, Others, A, Sentence]

Placing null at the end of the List [duplicate]

This question already has answers here:
Placing null at the end of the List
(5 answers)
Closed 8 years ago.
I have an arrayList of object like that: [object 1, object 2, null,null,..,null , object 3, null,null]
I try to move object 3 after object 2 without delete "null case", but it's doesn't work. So I would like to iterate my arrayList from right to left and check if the value is not null and then move Object 3 behind object 2. I precise that I don't know the number of "null case" between object 2 and Object 3
I try to write this:
ArrayList<Type> subList = new ArrayList<Type>();
for (int i = 0; i < array.size(); i++) {
subList = array.get(i);
for (int j = subList.size(); j >=0 ; j--) {
if(subList.get(j)!=null) {
Collections.swap(subList, j, j-1);
}
}
}
edit:
solution 1: that works for my project
for(int i=0;i<subList.size();i++)
if(subList.get(i)!=null) {
for(int j=0;j<i;j++) {
if (subList.get(j)==null) {
Collections.swap(subList,i,j);
break;
}
}
}
}
solution 2 : copy in other arraylist
doesn't work for my project, don't know why
List<String> strings = Arrays.asList(new String[]{"A", null, "B"});
List<String> result = new ArrayList<String>();
for(String string : strings) {
if(string != null)
result.add(string);
}
for (int i = 0, remaining = strings.size() - result.size(); i < remaining; i++) {
result.add(null);
}
Update 2:
To swap between object with out create any new List , Use Collections.swap() ; Something like this:
public static void main(String[] args) {
ArrayList subList = new ArrayList();
subList.add("1");
subList.add("2");
subList.add(null);
subList.add(null);
subList.add("3");
for(int i=0;i<subList.size();i++)
if(subList.get(i)!=null) {
for(int j=0;j<i;j++) {
if (subList.get(j)==null) {
Collections.swap(subList,i,j);
break;
}
}
}
}
}
Update 1:
Try this :
public static void main(String[] args) {
ArrayList subList = new ArrayList();
subList.add("1");
subList.add("2");
subList.add(null);
subList.add(null);
subList.add("3");
subList=leftShift(subList);
}
public static ArrayList leftShift(ArrayList x){
ArrayList temp=new ArrayList();
int count=0;
for(Object t:x){
if(t!=null)
temp.add(t);
else
count++;
}
for (int i=0;i<count;i++)
temp.add(null);
return temp;
}
solution from top of my head, is not brilliant, but it will allow you to keep order
int nullIndex = -1;
for (int i = 0; i < list.size(); i++) {
if (nullIndex==-1 && list.get(i) == null) {
System.out.println("nullIndex ="+i);
nullIndex = i;
} else if (nullIndex >= 0 && list.get(i) != null) {
System.out.println("swap ="+i+" "+nullIndex);
list.set(nullIndex, list.get(i));
list.set(i, null);
i = nullIndex;
nullIndex=-1;
}
}
sorry i forgot you are using arraylist, you can do this simpler
int counter=0;
while(subList.contains(null)){
subList.remove(null);
counter++;
};
while(counter>0){
subList.add(null);
counter--;
}

How to print the string without duplicate?

I tried to print the string without duplicate but i not getting the proper output and here I exposed my code snippets.
class Duplicatestring
{
public static void main(String [] args)
{
String word = "";
String[] ip ={"mani" ," manivannan","raghv ","mani"};
for(int i =0; i<ip.length; i++)
{
for(int j = i+1; j<=ip.length; j++)
{
if(ip[i].equals(ip[j])){
word = word+ip[i];
}
}
System.out.println(word);
}
}
}
And one more thing is I don't want use the collections that is my task and pleas give any proper solution for this.
Example:
Input -> {mani, manivanna,raghv, mani};
output -> {mani, manivanna,raghv}
If you don't want to use collections then I assume it's a homework, so I don't want to provide you a full solution, but I'll guide you.
You can have a helper array of the size of the original array. Now you write two nested loops and for each word, if you find a duplicate, you mark the helper array with 1.
After this procedure you'll have something like this in the helper array:
[0,0,0,1]
Now you iterate on the arrays in parallel and print the element only if the corresponding index in the helper array is 0.
Solution is O(n2).
Your loop is incorrect.
To solve the problem, you can use a Set to eliminate duplicated words.
If the problem must be solved by O(n^2) loops, the following code will work:
public class Duplicatestring {
public static void main(String[] args) {
String[] ip = { "mani", " manivannan", "raghv ", "mani" };
for (int i = 0; i < ip.length; i++) {
boolean duplicated = false;
//search back to check if a same word already exists
for (int j = i - 1; j >= 0; j--) {
if(ip[i].equals(ip[j])) {
duplicated = true;
break;
}
}
if(!duplicated) {
System.out.println(ip[i]);
}
}
}
}
if you want to remove the duplicate from the array call the below method and pass the array has the duplicate values.. it will return you the array with non-duplicate values..
call method here
ip = removeDuplicates(ip);
public static int[] removeDuplicates(int[] arr){
//dest array index
int destination = 0;
//source array index
int source = 0;
int currentValue = arr[0];
int[] whitelist = new int[arr.length];
whitelist[destination] = currentValue;
while(source < arr.length){
if(currentValue == arr[source]){
source++;
} else {
currentValue = arr[source];
destination++;
source++;
whitelist[destination] = currentValue;
}
}
int[] returnList = new int[++destination];
for(int i = 0; i < destination; i++){
returnList[i] = whitelist[i];
}
return returnList;
}
it will return you the non duplicates values array..!!
u may try this:
public class HelloWorld{
public static void main(String []args){
String[] names = {"john", "adam", "will", "lee", "john", "seon", "lee"};
String s;
for (int i = 0; names.length > i; i ++) {
s = names[i];
if (!isDuplicate(s, i, names)) {
System.out.println(s);
}
}
}
private static boolean isDuplicate(String item, int j, String[] items) {
boolean duplicate = Boolean.FALSE;
for (int i = 0; j > i; i++) {
if (items[i].equals(item)) {
duplicate = Boolean.TRUE;
break;
}
}
return duplicate;
}
}
output
john
adam
will
lee
seon
if string order does not matter for you, you can also use the TreeSet.. check the below code.. simple and sweet.
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;
public class MyArrayDuplicates {
public static void main(String a[]){
String[] strArr = {"one","two","three","four","four","five"};
//convert string array to list
List<String> tmpList = Arrays.asList(strArr);
//create a treeset with the list, which eliminates duplicates
TreeSet<String> unique = new TreeSet<String>(tmpList);
System.out.println(unique);
System.out.println();
Iterator<Integer> iterator = unique.iterator();
// Displaying the Tree set data
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}
it will print as -
[five, four, one, three, two]
five
four
one
three
two

Java Alphabetizer

I'm trying to make a program in which I ask the user to input words, and then the program puts them in Alphabetical Order. Here's what I've got so far:
import java.util.Scanner;
public class WordAlphabeticalizer {
/**
* #param args
*/
public static void main(String[] args) {
// Variables and Objects
String arraylength;
Scanner input = new Scanner (System.in);
// Code
System.out.println("Please input how many terms you would like to alphabetize"):
arraylength = input.nextLine();
String[] words = new String[Integer.parseInt(arraylength)];
for(int index = 0; index < words.length; index ++){
System.out.println("Please input word number " + (index + 1) + ":");
words[index] = input.nextLine();
}
}
}
I would like to know how to go about comparing the first letters of each word in the array, and what logic I would use to keep going to compare the word to the first two, three, or how many ever spaces it needs to go in order to get which word goes first, and then the word that goes after it. Any ideas?
java.lang.String implements the java.lang.Comparable interface so you can sort them by adding them to a sorted collection (Try java.util.TreeSet)
Set<String> stringsToSort = new TreeSet<String>();
stringsToSort.add("Fish");
stringsToSort.add("Dog");
stringsToSort.add("Cat");
System.out.println(stringsToSort);
Though it's a bit verbose, this is a method I've used to alphabetise Strings:
public static String[] alphabetise(final String[] array)
{
Arrays.sort(array, new Comparator<String>()
{
#Override
public int compare(final String o1, final String o2)
{
if(o1 == null && o2 == null)
{
return 0;
}
else if(o1 == null)
{
return -1;
}
else if(o2 == null)
{
return 1;
}
else if(o1.equals(o2))
{
return 0;
}
else if(o1.isEmpty())
{
return -1;
}
else if(o2.isEmpty())
{
return 1;
}
final Character[] c1 = toCharacterArray(o1.toLowerCase());
final Character[] c2 = toCharacterArray(o2.toLowerCase());
final int max = Math.max(c1.length, c2.length);
for(int i = 0; i < max; i++)
{
if(i < c1.length && i < c2.length)
{
final int comp = c1[i].compareTo(c2[i]);
if(comp != 0)
{
return comp;
}
}
else return new Integer(c1.length).compareTo(new Integer(c2.length));
}
return 0;
}
});
return array;
}
static Character[] toCharacterArray(final String str)
{
if(str == null || str.isEmpty()) return new Character[0];
final Character[] array = new Character[str.length()];
int counter = 0;
for(final char c : str.toCharArray())
{
array[counter++] = c;
}
return array;
}
This will conform to proper alphabetical order, ignoring capitals and favouring shorter words over longer (e.g. "House" before "Houses").

Categories

Resources