This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Removing an element from an Array (Java)
How to remove specific String array value for example
String[] str_array = {"item1","item2","item3"};
i want to remove "item2" from str_array pls help me i want output like
String[] str_array = {"item1","item3"};
I would do it as follows:
String[] str_array = {"item1","item2","item3"};
List<String> list = new ArrayList<String>(Arrays.asList(str_array));
list.remove("item2");
str_array = list.toArray(new String[0]);
If you must use arrays, System.arraycopy is the most efficient, scalable solution. However, if you must remove one element from an array several times, you should use an implementation of List rather than an array.
The following utilizes System.arraycopy in order to achieve the desired effect.
public static Object[] remove(Object[] array, Object element) {
if (array.length > 0) {
int index = -1;
for (int i = 0; i < array.length; i++) {
if (array[i].equals(element)) {
index = i;
break;
}
}
if (index >= 0) {
Object[] copy = (Object[]) Array.newInstance(array.getClass()
.getComponentType(), array.length - 1);
if (copy.length > 0) {
System.arraycopy(array, 0, copy, 0, index);
System.arraycopy(array, index + 1, copy, index, copy.length - index);
}
return copy;
}
}
return array;
}
Also, you can increase the method's efficiency if you know that your array consists of only Comparable objects. You can use Arrays.sort to sort them before passing them through the remove method, modified to use Arrays.binarySearch to find index rather than a for loop, raising that portion of the method's efficiency from O(n) to O(nlogn).
Other Option is to copy array to other array accept than remove item.
public static String[] removeItemFromArray(String[] input, String item) {
if (input == null) {
return null;
} else if (input.length <= 0) {
return input;
} else {
String[] output = new String[input.length - 1];
int count = 0;
for (String i : input) {
if (!i.equals(item)) {
output[count++] = i;
}
}
return output;
}
}
Related
Im trying to figure out a way to override a specific array in this scenario.
Im iterating through a LinkedList and when I encounter the Element null I am supposed to add the index of the Element to an already defined array of ints.
public int [] indexes()
{
int [] result = new int [0];
int counter = 0;
Element current = first;
int k = 0;
for(int i = 0 ; i< size() ; i++)
{
if(current.getContent()==null)
{
counter++;
}
}
int [] temp = new int [counter];
current = first;
for(int i = 0 ; i< size() ; i++)
{
if(current.getContent()==null)
{
temp[k++] = i ;
}
}
result = temp;
return result;
As you can already see, I have an array with no elements in it and a length of 0.
Afterwards Im iterating through the List to check if and how many Elements are null. When I find one I increment the counter.
I set up a new temporary array with the length of the counter and the fill the temporary Element with the indexes.
1st Question : Does the line result = temp; work as intended? Does the array called result now contain the array of temp?
2nd Question : How can I check if an Element is null in a LinkedList without getting a NullpointerException? I tried using the following in my if conditions:
current == null
current.getContent() == null
current.equals(null)
current.getContent().equals(null)
All of those returned a counter of 0 which means it didnt increment the counter when encountering a Null-Element. How can I rewrite the if conditions?
Question 1: Yes. result and temp refer to the same data.
Question 2: your for loop is problematic:
for(int i = 0 ; i< size() ; i++)
{
if(current.getContent()==null)
{
temp[k++] = i ;
}
}
You're not changing current, so it's always pointed to the first element.
I'm not sure if you're using Java's LinkedList<> or implementing your own.
I wrote this little program. I think it demonstrates what you're trying to do:
import java.util.*;
public class Foo {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();;
list.add("Hello");
list.add("There");
list.add(null);
for (String str: list) {
System.out.println(str != null ? str : "<null>");
}
ArrayList<Integer> indexes = new ArrayList<Integer>();
int index = 0;
for (String str: list) {
if (str == null) {
indexes.add(index);
}
++index;
}
for (Integer thisIndex: indexes) {
System.out.println(thisIndex);
}
}
}
At the end, you would need to convert from ArrayList into an int[]. But the output from this little guy is:
$ javac Foo.java && java Foo
Hello
There
<null>
2
I was able to override the result array with this line.
result = temp;
Also the way to check if an Element is null in the List was:
current.getContent() == null;
And last I actually forgot setting the current pointer to the next Element which actually was my biggest problem:
current = current.getSucc();
Thanks for everyone's help and time. I really appreciate it!
I have an array of strings and I need to sort it before I return it. The issue is that two of those values must come first. I tried a few things (including what is below), but I can't seem to figure it out.
What I have below clearly doesn't work because I sort it twice in some cases. I know I can change the array to a list and then use Collections.reverse, but is there a better way that doesn't involve changing structures? I added a simple example below
public static String[] getStrings() {
String[] array = {"d","a","c","e","b"};
boolean first = false;
boolean second = false;
int left = 0;
for (int right = 0; right < array.length; right++) {
if (array[right].equals("e")){
first = true;
array[right] = array[left];
array[left] = "e";
left++;
}
}
if (first) {Arrays.sort(array, left, array.length);}
left = 0;
for (int right = 0; right < array.length; right++) {
if (array[second].equals("c")){
second = true;
array[right] = array[left];
array[left] = "c";
left++;
}
}
if (second) {Arrays.sort(array, left, array.length);}
if (!first && !second) {Arrays.sort(array);}
}
return array;
}
EDIT
Using the array in the example d,a,c,e,b. After the sorting it should be c,e,a,b,d
The two exceptions alphabetically, following the rest of the array alphabetically as well.
You can use the Java 8 Stream API.
final String[] array = {"d","a","c","e","b"};
final Set<String> search = Stream.of("c", "e").collect(toSet());
final String[] result = Stream.concat(
Stream.of(array).filter(search::contains).sorted(),
Stream.of(array).filter(s -> !search.contains(s)).sorted()
).toArray(String[]::new);
The first part selects the "c" and "e" strings and sort them individually, then anything that is not "c" or "e" is selected and sorted individually. Finally, the two streams are concatenated into an array.
How about implementing custom Comparator?
String[] array = {"d","a","c","e","b"};
Arrays.sort(array, new Comparator<String> () {
int compare(String s1, String s2) {
if (firstOne.equals(s1) && firstOne.equals(s2)) {
return 0;
} else if (firstOne.equals(s1) {
return -1;
} else if (firstOne.equals(s2)) {
return 1;
}
if (secondOne.equals(s1) && secondOne.equals(s2)) {
return 0;
} else if (secondOne.equals(s1) {
return -1;
} else if (secondOne.equals(s2)) {
return 1;
}
return s1.compareTo(s2);
});
Refer to
https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#sort(T[],%20java.util.Comparator)
Take the indices of the elements that you don't want sort and move those elements to the front of the list, then sort the rest of the list.
public static String[] getString(String[] strArray, int... firstElems) {
// Move the elements that are not sorted to the front
int g = 0;
for (int f = 0; f < firstElems.length; f++, g++) {
String elem = strArray[g];
strArray[g] = strArray[firstElems[f]];
strArray[firstElems[f]] = elem;
}
// Sort the rest
Arrays.sort(strArray, g, strArray.length);
return strArray;
}
There is short solution based #ikicha's and Java 8:
final String first = "c", second = "e";
Arrays.sort(array, (i, j) -> {
if (i.equals(first) || (i.equals(second) && !j.equals(first))) {
return -1;
} else {
return i.compareTo(j);
}
});
Why don't you sort it first, then lookup the two values, and shift them upfront?
Worst case would be n*log(n)+2n.
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 need to create a method to remove an element from an array of objects, without turning it into an ArrayList.
This is the constructor for my object:
public Person(String name1, String telno1)
{
name = name1;
telno = telno1;
}
And my Array:
int capacity = 100;
private Person[] thePhonebook = new Person[capacity];
And i have a shell for my remove method:
public String removeEntry(String name)
{
//name is name of the person to be removed (dont worry about duplicate names)
//returns the telephone number of removed entry
}
Im not sure how to delete the element in the array (i dont want to just set the values to null)
I did think of creating a new array and copying parts on either side of the element to be removed to form a new array but im not sure how to implement that.
I also have a find method which can be used to find the name of the person in the array if that helps:
private int find(String name)
{
String name1 = name;
int i = 0;
int elementNo = 0;
int found = 0;
while(i < size)
{
if(thePhonebook[i].getName().equals(name1))
{
elementNo = i;
found = 1;
break;
}
}
if(found == 1)
{
return dirNo;
}
else
{
dirNo = -1;
return dirNo;
}
}
Thanks for your time.
You cannot directly remove an element from an array in Java. You two choices:
A. If you must preserve the order of the elements in the array: Begin at the index you want to remove, and shift each element "down" one index (toward index 0), as in:
public String removeEntry(String name)
{
String result = null;
int index = find(name);
if (index >= 0)
{
result = thePhonebook[index].telno;
for (int i = index + 1; i < thePhonebook.length; ++i)
{
thePhonebook[i - 1] = thePhonebook[i];
if (thePhonebook[i] == null)
{
break;
}
}
thePhonebook[thePhonebook.length - 1] = null;
}
return result;
}
In the above implementation, the value null in the array signifies the end of the list.
B. If the order of the elements in the array doesn't matter: Swap the element you want to remove with the last element of the list. Note that to do this you need to maintain a length value for the list, which is the value thePhonebookLength in the code below.
public String removeEntry(String name)
{
String result = null;
int index = find(name);
if (index >= 0)
{
result = thePhonebook[index].telno;
thePhonebook[index] = thePhonebook[thePhonebookLength - 1];
thePhonebook[--thePhonebookLength] = null;
}
return result;
}
A benefit of both of these solutions is that the array is modified in place, without using allocation.
Having offered these possibilities, I suggest that using a collection is better suited for your purposes -- such as one of the List subclasses, or perhaps even a Map if lookups by name are common.
To do this is to get the last index in your array and then pass it to the one that was just deleted and the delete the last array.. if the array is the last one dont it just delete it..
for(int i = 0; i < thePhonebook .length; i++)
{
if(thePhonebook[i].getName().equals(string))
{
if(i == thePhonebook .length - 1)
thePhonebook[i] = null;
else
{
thePhonebook[i] = null;
thePhonebook[i] = thePhonebook[thePhonebook .length - 1];
thePhonebook[thePhonebook .length - 1] = null;
}
}
}
I want a command such as this:
setstat <statname> <level>
However, my 'statname's are in a Array; and I need to output the Array number.
This is the code I am using:
String[] statname = {"att", "def", "str", "hp",
"ranged", "pray", "magic", "cooking",
"wc", "fletch", "fish", "fm",
"craft", "smith", "mining", "herb",
"agil", "thieving", "slayer", "farming", "rc"};
int statid = statname.contains(arg[1]);
However, it doesn't work (for me). Seeing as contains(...) isn't compatible with an String[] array.
I have no idea which method to use, or how to handle this.
Use Arrays.asList(statname).indexOf(arg[1]); to find the index of an item.
Since your array is not ordered, this function will work:
public int getFoundIndex(String[] stringArr_toSearch, String str_toFind)
for(int i = 0; i < stringArr_toSearch.length; i++) {
if(stringArr_toSearch[i].equals(str_toFind)) {
return i;
}
}
return -1;
}
Call it with
int foundIdx = getFoundIndex(statName, "str");
Here's a neat code for the linear search which returns the index of the element in the array if the element is found, else returns false.
public int search(String[] array, String element)
{
if(array == null || element == null)
return -1;
for(int i = 0; i < array.length; i++)
{
if(array[i].equals(element))
return i;
}
return -1;
}
Using the approach: Arrays.asList(statname).indexOf(arg[1); can get expensive, if you have to search for the elements a lot of time.
You can sort your array once, and then do a binary search too, in order to achieve faster lookup times, if you have to search for elements in the statname array multiple times.