Java Mixing variable String[] with String in one only array of strings - java

Suppose this:
String s0 = "01234";
String[] S1 = {"jkl","abc","xyz"};
String[] S2 = {"OPQ","ghi","STU"};
String s3 = "56789";
get_AllStrings(s3, S1, S2, s0);
The returned String[] must be:
String[] NewArray = {"56789","OPQ","ghi","STU","01234"}
I want to obtain this strings like only one array of strings...
Here my method:
public String[] get_AllStrings(String... argString) { //Only String or String[]
int TheSize = 0;
for (int i = 0; i<argString.length; i++) {
if(argString[i]!= null && argString[i].getClass().isArray()) {
String[] OneArray = (String [])argString[i];
TheSize += OneArray.length;
} else {
TheSize += 1;
}
}
String[] NewArray = new String[TheSize];
int ThePos = 0;
for (int i = 0; i<argString.length; i++) {
if(argString[i]!= null && argString[i].getClass().isArray()) {
String[] OneArray = argString[i];
System.arraycopy(OneArray, 0, NewArray, ThePos, OneArray.length);
ThePos += OneArray.length;
} else {
String[] OneArray = {argString[i]};
System.arraycopy(OneArray, 0, NewArray, ThePos, 1);
ThePos += OneArray.length;
}
}
return NewArray;
}
But, is not working...

What you want to do is to use an ArrayList instead of an array.
public static String[] getAllStrings(Object ... argString) {
ArrayList<String> list = new ArrayList<String>();
for (Object stringOrArray : argString) {
if (stringOrArray instanceof String)
list.add((String) stringOrArray);
else {
String[] strings = (String) stringOrArray;
list.addAll(Arrays.asList(strings));
}
}
return list.toArray(new String[list.size()]);
}

I changed your code a bit and got this:
public static String[] get_AllStrings(Object... argString) {
ArrayList<String> strings = new ArrayList<String>();
for (int i = 0; i<argString.length; i++) {
if(argString[i]!= null && argString[i].getClass().isArray()) {
String[] OneArray = (String [])argString[i];
for(String str : OneArray)
strings.add(str);
} else {
strings.add((String)argString[i]);
}
}
return (String[])strings.toArray();
}
I could not get it to accept both String and String[] with your method signature, but a change to Object... did the trick. You can use an ArrayList to create the array directly instead of looping through everything twice.

unfortunately, you're running up against Java's type system here.
String and String[] are not subtypes.
so a variable, or array can only hold one or the other.
Using object, as done by #Johan Henriksson throws away any type safety assurances from the compiler, since any object can be put in the array. this is okay if you have some garuantee that you'll only ever have Strings, and you'll need to cast to string on pulling out of the collection.
I'm not sure exactly what you're trying to achieve here
So I'm not sure how to go about resolving this.
if you just want all the strings from all sources in a collection of some sort, I'd use a list
it's unclear where you're getting these strings and string arrays from however.

You can't pass a String[] into an element of a varargs String... parameter.
The only way to accept either String or String[] is a "typeless" varargs Object..., because Object is the only common type to both.
public static String[] get_AllStrings(Object... args) {
ArrayList<String> result = new ArrayList<String>();
for (Object o : args) {
if (o instanceof String) {
result.add((String)o);
} else if (o instanceof String[]) {
result.addAll(Arrays.asList((String[])o));
} else {
throw new IllegalArgumentException();
}
}
return (String[])result.toArray();
}

Related

Getting rid of empty elements in ArrayList

I've been working on this question for a while and I'm still stumped.
I'm supposed to write a method stutter that takes an ArrayList<String> as a parameter and that replaces every string with two of that string. For example, if the list stores the values {"how", "are", "you?"} before the method is called, it should store the values {"how", "how", "are", "are", "you?", "you?"} after the method finishes executing.
But despite my best efforts I still can't seem to get rid of the empty elements that are in my code.
Any help would be greatly appreciated.
public static ArrayList<String> stutter(ArrayList<String> lst) {
ArrayList<String> list = new ArrayList<String>();
int size = lst.size();
int intSize = lst.size();
int inSize = lst.size();
int size4 = list.size();
if (lst.size() == 0) {
lst.clear();
} else {
for (int x = 0; x < size; x++) {
for (int i = 0; i < 2; i++) {
lst.add(lst.get(x));
}
}
for (int x = 0; x < intSize ; x++) {
lst.set(x,"");
}
for (int x = inSize - 1; x < size; x++) {
String oldInfo = lst.get(x);
list.add(oldInfo);
}
list.removeAll("",null);
}
return list;
}
Try this approach:
public void duplicate(final List<String> inputList) {
final List<String> temp = new ArrayList<>();
inputList.forEach(element -> {
temp.add(element);
temp.add(element);
});
inputList.clear();
inputList.addAll(temp);
}
Basically what I am doing here: another list called temp is used to store each element from your initial list 2 times. After that I just clean the initial list and add new stuff.
Instead of clear and addAll you can just return temp - it contains data as you need. But don't forget to change method return type from void to List<String> in that case.
Happy Coding :)
Try this
public static ArrayList<String> stutter(ArrayList<String> lst) {
ArrayList<String> list = new ArrayList<String>();
if (!lst.isEmpty()) {
for (String string : lst) {
list.add(string);
list.add(string);
}
}
return list;
}
}
this could do what you need , its basically checks list if not empty and duplicate the strings in the list
Following up on already good answers, here is my example with keeping the original sample method signature:
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class Stutter {
public static List<String> stutter(final List<String> words) {
// Create the response array.
List<String> response = new ArrayList<>();
// Check for valid arguments. If not, return empty array of words.
if (words == null || words.size() <= 0) {
return response;
}
// Iterate over the words that were passed in.
for (final String word : words) {
// Add the words twice to the response.
response.add(word);
response.add(word);
}
// The stutter response.
return response;
}
public static void main(final String[] args) {
final String[] myWords = { "hello", "world" };
final List<String> myStutterWords = stutter(new ArrayList<>(Arrays.asList(myWords)));
for (final String s : myStutterWords) {
System.out.println(s);
}
}
}

Convert Arrays inside ArrayDeque to String

I am trying to return a string pulled from the 2nd element of a given array inside of an ArrayDeque
I tried casting it and toString and concatenation after ToArray but I get this... I need to return it as a String
"The type of the expression must be an array type but it resolved to String"
ArrayDeque<String[]> bindings_and_var = new ArrayDeque();
public ArrayDeque<String[]> pushBindings(String var, String bindings) {
//var first element, bindings 2nd
String[] this_bindings_and_var = new String[2];
bindings_and_var.addLast(this_bindings_and_var);
return bindings_and_var;
}
public ArrayDeque<String[]> bindingsVal() {
return bindings_and_var;
}
public String lookup(int index) {
String[] array = (String[]) bindings_and_var.toArray();
//PROBLEM AREA vvv
String s = "" + array[index][1];
return s;
Your lookup method should look like this:
public String lookup(int index)
{
int counter = 0;
for (Iterator<String[]> itr = bindings_and_var.iterator(); itr.hasNext();)
{
String[] t = itr.next();
if (counter == index)
{
return t[1];
}
counter++;
}
}
You have defined your Deque as String[] while when you are doing bindings_and_var.toArray(); you would receive object array with each object as String array. Try,
Object[] array = (String[]) bindings_and_var.toArray();
Object obj = array[index];
String[] myArray = (String[])obj;
String s = "" + myArray[1];
Or
int i = 0;
for (String[] s : bindings_and_var) {
if (i == index) {
return s[1];
}
i++;
}
so that you don't have to iterate the whole collection.

How to return a String Array

My code is supposed to separate a given String and covert the chosen letters into # and separate and concatenate the words with the chosen letter. My problem is with one of the methods (allWordsWith) in my code, it won't allow me to return a String array. (p.s, the codes that run this one are irrelevant, I'm not supposed to edit those).
import java.util.Arrays;
import java.util.Scanner;
public class LipogramAnalyzer {
private String line;
public LipogramAnalyzer(String text){
line = text;
}
public String mark (char letter){
String replaceletters = line.replace(letter, '#');
return replaceletters;
}
public String[] allWordsWith (char letter){
String[] arr = line.split(" ");
for ( String ss : arr) {
String ary[] = {ss};
for(int i = 0; i < ary.length; i++){
int numindex = ss.indexOf(letter);
if (numindex != -1){
String result = ary[i];
return result;
}
}
}
}
}
"It won't allow me to return a String array"
Sure it will. You're attempting to return a String:
String result = ary[i];
return result;
Even though the return type is a string array:
public String[] allWordsWith (char letter){
You need to return an array, as allWordsWith implies you want multiple values.
But the bigger problem is that you are initializing the result array to a single element
String ary[] = {ss};
and thes lengths of arrays can't be changed after initialization. This means that ary.length in this loop
for(int i = 0; i < ary.length; i++){
will always equal one. That is not what you want.
In addition, you are searching the strings in the result array (ary), even though you just created it, meaning it has nothing in it--that is, all the values are null.
If you want a list of all the strings in line that have the letter in it, try
public String[] allWordsWith (char letter){
String[] asAllWordsInLine = line.split(" ");
java.util.ArrayList<String> alsAllWordsWithChar = new java.util.ArrayList<String>();
for ( String ss : asAllWordsInLine) {
if(ss.indexOf(letter) != -1) {
alsAllWordsWithChar.add(ss);
continue; //No need to check any more letters.
}
}
return alsAllWordsWithChar.toArray(new String[alsAllWordsWithChar.size()]);
}
I've changed the array to a list, since you can't know how many strings will have letter in it. A list can change size, an array can't. When no strings match, this returns an empty array, which is preferred over null. (more info)
I've also made the variable names more meaningful, and stopped checking a word after it matches a character (with continue, which short-circuits the current for-loop iteration).
Finally, the function is not returning anything until all strings have been analyzed, meaning after the for-loop completes. In your original code the return is inside the loop, meaning only the first string is returned.
A useful testing function:
public static final void main(String[] igno_red) {
testLine('b', "abc def ghi cba def ghi");
}
private static final void testLine(char c_letter, String s_line) {
System.out.println("Line: \"" + s_line + "\"");
String[] asAllWordsWith = (new LipogramAnalyzer(s_line)).allWordsWith(c_letter);
System.out.println("Words with '" + c_letter + "': " + Arrays.toString(asAllWordsWith));
}
Return the ary not ary[i]
for(int i = 0; i < ary.length; i++){
int numindex = ss.indexOf(letter);
if (numindex != -1){
String result = ary[i];
/*here*/ return ary;
}
You can return an array. Try return ary instead of return ary[i].
Also, your function must return something in all cases. In other words, you have to have a return statement after your for loops.
public String[] allWordsWith (char letter){
String[] arr = line.split(" ");
for ( String ss : arr) {
String ary[] = {ss};
for(int i = 0; i < ary.length; i++){
int numindex = ss.indexOf(letter);
if (numindex != -1){
String result = ary[i];
// or here return ary;
}
}
}
return ary;
}
Return the array
You are trying to return a String instead of String[] (String array)
Change the code:
if (numindex != -1) {
String result = ary[i];
return result;
}
To:
if (numindex != -1) {
return new String[]{ary[i]};
}
// afrer first for loop
return arr;
If you want to return a complete String-Array at once, I have modified your function (not tested):
public String[] allWordsWith (char letter){
String[] arr = line.split(" ");
String[] result = new String[ary.length];
for ( String ss : arr) {
String ary[] = {ss};
for(int i = 0; i < ary.length; i++){
int numindex = ss.indexOf(letter);
if (numindex != -1){
result[i] = ary[i];
}
}
}
return result;
}
As already said, you're returning a String instead of a String[]. Also note that your code will only ever return a single "word". I modified your code to add every word that contains your character and add it to a List. At the end of the loop the List is converted to a String[].
public String[] allWordsWith(char letter)
{
String[] arr = line.split(" ");
List<String> result = new ArrayList<>();
for (String ss : arr) {
int numindex = ss.indexOf(letter);
if (numindex != -1) {
result.add(ss);
}
}
return result.toArray(new String[result.size()]);
}

How to "minify" an array - Java

So suppose I create an array with 5 spaces, like so - String[] myArray = new String[5]. Then suppose I define some of those items, but leave some of them null (or whatever the Java term is for an undefined array item/variable), like so:
myArray[0] = "foo";
myArray[2] = "bar";
myArray[4] = "foobar";
Is there a way I can "minify" that array, squeezing out all the null items (not changing the size of it)? So that the index of "foo" stays at 0, but "bar"'s index becomes 1, and "foobar" resides at 2, with the last 2 spaces being empty? Long story short - shuffle around the items in an array, pushing all the null items to the end, while maintaining the relative order of the other items. Is there already a predefined Java method for that, or do I need to make my own?
You could use the following approach (without overhead of Collections instance):
import java.util.Arrays;
public class ArraySample {
public static void main(final String[] args) {
String[] src = new String[] { "foo", null, "bar", null, "foobar" };
String[] dest = new String[src.length];
int i = 0;
for (String s : src) {
if (s != null) {
dest[i++] = s;
}
}
System.out.println(Arrays.toString(src));
System.out.println(Arrays.toString(dest));
}
}
You can do it with only the source array :
String[] src = new String[] { "foo", "foo3", null,null, "bar", null,null, "foobar", "foo2", null,"foo5",null };
int lastNullIdx = -1;
for (int i=0; i <src.length ; i++) {
if (src[i] == null) {
if(lastNullIdx==-1)lastNullIdx=i;
}
else if(lastNullIdx!=-1){
src[lastNullIdx++]=src[i];
src[i]=null;
}
}
System.out.println(Arrays.toString(src));
In-place minification, simpler code:
public static String[] minify(String[] x) {
int d = 0;
for (String s : x) if (s != null) x[d++] = s;
while (d < x.length) x[d++] = null;
return x;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(
minify(new String[] {"foo", null, "bar", null, "foobar"})));
}
Don't think that there is a method for it. If therewould be something like that, it would be in java.util.Arrays. I would do it like this
String[] src = new String[] { "foo", null, "bar", null, "foobar" };
for (int c = 0, j = 0; c < src.length; c++) {
if (src[c] != null) {
src[j++] = src[c];
src[c] = null;
}
}
edit:
String[] src = new String[] { "foo", null, "bar", null, "foobar" };
Comparator<String> NEW_ORDER = new Comparator<String>() {
public int compare(String e1, String e2) {
if(e1 == null)return 1;
if(e2 == null)return -1;
return 0;
}
Arrays.sort(src, NEW_ORDER);
Should work aswell, since Arrays.sort is a stable sort, but i think the other solution is better, since its O(n) and not O(n log n)
With functionaljava,
array(myArray).filter(new F<String, Boolean>() {
public Boolean f(String s) {
return s != null;
}
});
This will retain the elements that satisfy the given conditions. The result will be the new array returned by filter.
Edit:
Sorry, I misread the question before. Here's how you can squeeze out nulls to right.
array(myArray).sort(
booleanOrd.comap(new F<String, Boolean>() {
public Boolean f(String s) {
return s == null;
}
})
);
Java is already prepared for such sorting problem using the Arrays.sort(T[] a, Comparator c) method:
Arrays.sort(myArray, new StringNullComparator());
with
class StringNullComparator implements Comparator<String> {
#Override
public int compare(String s1, String s2)
{
if(s1==null && s2!=null) return 1;
else if(s1!=null && s2==null) return -1;
else return 0;
}
}
This way you can even sort the null values to lower indecees by inverting the value returned from the compare method.

How to remove null from an array in 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.

Categories

Resources