I am trying to implement my own ArrayList.
This is the code I have so far:
public class StringArrayList {
private int size = 0;
private String[] strings = new String[0];
// Constructors
public StringArrayList(){
strings = new String[size];
};
public StringArrayList(int initialCapacity){
strings = new String[0];
}
public StringArrayList(String[] strings){
this.strings = strings;
size = strings.length;
}
public int size() {
return size;
}
public String get(int index){
return strings[index];
}
public boolean add(String content){
boolean add = false;
strings = new String[10];
for(int i = 0; i < strings.length; i++){
if(strings[i] == null) {
strings[i] = content;
return true;
}
}
return add;
}
I have to make following test succeed:
public void add__given_empty_list__then_adds_string()
{
StringArrayList lst = list();
lst.add( "string" );
assertSameItems( list( "string" ), lst );
}
I am getting this error:
java.lang.AssertionError: expected<1> but was <0>
I'm actually lost in what is asked of me. I know there is a difference between null and an empty list, but if I don't specify then null I'm getting ArrayOutOfBounds exceptions.
What am I not understanding.
Thank you
Your implementation has a few errors.
public StringArrayList(int initialCapacity){
strings = new String[0];
}
This type of constructor is meant to allocate with the initial capacity, not with "0".
And most importantly, your add method doesn't actually add a new element, but overwrites your current internal array, and places a new element at the 0th index (without incrementing the size variable).
public boolean add(String content){
boolean add = false; //unnecessary, can replace bottom `add` with `false` for same result
strings = new String[10]; //overwrites internal array of "list" with a new array
for(int i = 0; i < strings.length; i++){
if(strings[i] == null) { //will always replace only first element as this is a new array
strings[i] = content;
return true;
}
}
return add;
}
The size variable is meant to keep track of how many elements the current array contains (which would be incremented when you add a new element).
Knowing that, you'd be able to add a new element instrings[size] to add a new element, in case size < strings.length was true.
If that condition is not met (you want to add more than the current capacity), it should "resize" the internal array by creating a new array, copying all previous elements into the new array, then replacing the old array, and adding the new element to the new array.
EDIT: Your new code
public boolean add(String content) {
strings = new String[strings.length+1]; //still erases the internal array!
strings[0] = content; //only modifies the first element, rather than add to the list
size = 1; //if it was implemented correctly, this would be size++;
return true;
}
Make a test that adds TWO elements to the list, and assert if the list contains both of them.
EDIT2:
Here is a solution that ought to work:
public class StringArrayList {
private int size = 0;
private String[] strings;
// Constructors
public StringArrayList() {
this(0);
};
public StringArrayList(int initialCapacity){
String[] innerStrings = new String[initialCapacity];
this(innerStrings);
}
public StringArrayList(String[] strings){
this.strings = strings;
}
public int size() {
return size;
}
public String get(int index){
return strings[index];
}
public boolean add(String content){
if(size == strings.length) {
String[] newStrings = new String[size+10];
for(int i = 0; i < size; i++) {
newStrings[i] = strings[i];
}
strings = newStrings;
}
strings[size++] = content;
return true;
}
}
EDIT3:
public boolean add(String content){
if(size == strings.length) {
String[] temp_list = new String[strings.length]; //no need to allocate a new array here if this is just to store your current array
temp_list = strings;
strings = new String[size++]; //wrong, this allocates a `size`-long array and increases `size` by 1 afterwards, rather than create a new, larger internal array
strings = temp_list; //this just overwrites your internal array with the old array which is not increased in size
}
for(int i = 0; i < strings.length; i++) {
if(strings[i] == null) { //this is not necessary with proper `size`
strings[i] = content;
}
}
return true;
}
Your add implementation is incorrect.
It will always rewrite the internal strings array and set the passed argument to the first element.
The reason why it is failing is because the add(String) method does not increment the size variable.
Currently you are using if(strings[i] == null) { to determine where a new element should be added. But an arraylist can contain nulls...
I think there should be a difference between the length of the array (e.g. the capacity of the arraylist) and the size field.
The size field should probably indicate how many elements are currently in the list. When a new element cannot be added because size is equal to the array length then some work is needed to create a new, larger array and copy all the elements from the old to the new array.
BTW I noticed you are not using the initialCapacity parameter in a constructor. This should probably be used to initialize the array to that length.
Related
I have this question here
Once a player has drawn the top card from the deck, they must discard it.
Given a deck of cards, return a new deck containing all the cards except the first from the original deck.
Note: The new array returned is one element shorter than the original, except when the deck has no cards. Then the array returned must be empty.
So basically I have to make a new array thats the same as the old array minus the card at index 0. The issue im having is when I have to put an empty array and IntelliJ keeps throwing a NegativeArraySizeException.
public String[] discardTopCard(String[] remainingDeck) {
String[] newHand = new String[remainingDeck.length - 1];
String[] emptyArray = new String[] {};
int k = 0;
if (remainingDeck.length == 0 || remainingDeck.length == 1) {
return emptyArray;
}
for (int i = 1; i < remainingDeck.length; i++) {
newHand[k] = remainingDeck[i];
k++;
}
return newHand;
}
this is my current code.
I've also tried this and just setting it to null
public String[] discardTopCard(String[] remainingDeck) {
String[] newHand = new String[remainingDeck.length - 1];
int k = 0;
if (remainingDeck.length == 0 || remainingDeck.length == 1) {
return remainingDeck;
}
for (int i = 1; i < remainingDeck.length; i++) {
newHand[k] = remainingDeck[i];
k++;
}
return newHand;
}
If you want to work with a new array that is only part of an existing on, I would recommend to use an existing method: java.util.Arrays.copyOfRange
Example:
private static final String[] EMPTY_STRING_ARRAY = new String[0];
public String[] discardTopCard(String[] remainingDeck) {
int length = remainingDeck.length;
if (length < 2) {
return EMPTY_STRING_ARRAY;
}
return Arrays.copyOfRange(remainingDeck, 1, length);
}
I declared the empty string array as constant outside the method, because it is immutable and it's not necessary to create more than one instance in the whole program.
Both cases, empty input array and input array of lenght 1 will have the same result: an empty array.
Also note that usage of length in the copyOfRange method is OK because there it acts as "to"-index and not as number of elements to copy.
Or, even simpler:
public String[] discardTopCard(String[] deck) {
if (deck.length > 1)
deck = Arrays.copyOfRange(deck, 1, deck.length);
return deck;
}
How about this?
public String[] discardTopCard(String[] deck) {
if (deck.length == 0) {
return deck;
}
String[] smallerDeck = new String[deck.length - 1];
for (int i = 0; i < smallerDeck.length; i++) {
smallerDeck[i] = deck[i];
}
return smallerDeck;
}
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;
}
}
I have a .txt file which has data for states as given below:
AL,Alab,4860
AK,Alas,7415
AZ,Ariz,6908
AR,Arka,2988
I have made a function which counts how many states there are that start with the initial passed as such:
public int CInitial(char initial) {
int total = 0;
for(int i = 0; i < states.length; i++) { //states is an array which includes all states present in the .txt file
String testString = states[i].getName(); // getName gets the name of the states present in the .txt file
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
total++;
}
}
}
return total;
}
This would return the number 4 if "A" is passed and 0 if any other initial is passed as there are 4 states that begin with the letter "A".
Now how can I create a new function that passes a character and returns the name of all the states that begin with that character? For Instance this is the initial return type needed for this, however I'm having troubles starting this. Is the process identical to the countStatesCountByInitial function I created?
public State[] CByInitial(char initial) {
return new State[] {}; //to be completed
}
Yes, it will be very similar to the countStatesCountByInitial. The main difference is each time you find a match, you want to add the state into the array. Since we don't know the size of the array beforehand, we may want to use a List instead.
public State[] getStatesCountByInitial(char initial) {
ArrayList<State> found = new ArrayList<>();
// this is the same as before
for(int i = 0; i < states.length; i++) {
String testString = states[i].getName();
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
// except here when you find a match, you add it into the list
found.add(states[i]);
}
}
}
// return as array
return found.toArray(new State[found.size()]);
}
As suggested by Patrick, we can avoid using List by using countStatesCountByInitial to initialize the size of the states.
public State[] getStatesCountByInitial(char initial) {
int matchSize = countStatesCountByInitial(initial);
States[] found = new States[matchSize];
int foundIndex = 0;
// this is the same as before
for(int i = 0; i < states.length; i++) {
String testString = states[i].getName();
char[] stringToCharArray = testString.toCharArray();
for (char output : stringToCharArray) {
if(initial == output) {
// except here when you find a match, you add it into the array
found[foundIndex] = states[i];
foundIndex++;
}
}
}
// return the array
return found;
}
You can done both operations simply by one method.
public static ArrayList<State> getStatesCountByInitial(char initial) {
ArrayList selectedStates = new ArrayList<State>();
for(int i = 0; i < states.length; i++) {
if(states.charAt(0) == initial){
selectedStates.add(states[i]);
}
}
return selectedStates;
}
This method will return a arraylist.
If you want to get the count, call this method and get the size of the array.
ArrayList<State> statesNew = getStatesCountByInitial('A');
int count = statesNew.size();
I'm working on a program that uses an ArrayList to store Strings. The program prompts the user with a menu and allows the user to choose an operation to perform. Such operations are adding Strings to the List, printing the entries etc. What I want to be able to do is create a method called removeDuplicates(). This method will search the ArrayList and remove any duplicated values. I want to leave one instance of the duplicated value(s) within the list. I also want this method to return the total number of duplicates removed.
I've been trying to use nested loops to accomplish this but I've been running into trouble because when entries get deleted, the indexing of the ArrayList gets altered and things don't work as they should. I know conceptually what I need to do but I'm having trouble implementing this idea in code.
Here is some pseudo code:
start with first entry;
check each subsequent entry in the list and see if it matches the first entry;
remove each subsequent entry in the list that matches the first entry;
after all entries have been examined, move on to the second entry;
check each entry in the list and see if it matches the second entry;
remove each entry in the list that matches the second entry;
repeat for entry in the list
Here's the code I have so far:
public int removeDuplicates()
{
int duplicates = 0;
for ( int i = 0; i < strings.size(); i++ )
{
for ( int j = 0; j < strings.size(); j++ )
{
if ( i == j )
{
// i & j refer to same entry so do nothing
}
else if ( strings.get( j ).equals( strings.get( i ) ) )
{
strings.remove( j );
duplicates++;
}
}
}
return duplicates;
}
UPDATE: It appears that Will is looking for a homework solution that involves developing the algorithm to remove duplicates, rather than a pragmatic solution using Sets. See his comment:
Thx for the suggestions. This is part of an assignment and I believe the teacher had intended for the solution to not include sets. In other words, I am to come up with a solution that will search for and remove duplicates without implementing a HashSet. The teacher suggested using nested loops which is what I'm trying to do but I've been having some problems with the indexing of the ArrayList after certain entries are removed.
Why not use a collection such as Set (and an implementation like HashSet) which naturally prevents duplicates?
You can use nested loops without any problem:
public static int removeDuplicates(ArrayList<String> strings) {
int size = strings.size();
int duplicates = 0;
// not using a method in the check also speeds up the execution
// also i must be less that size-1 so that j doesn't
// throw IndexOutOfBoundsException
for (int i = 0; i < size - 1; i++) {
// start from the next item after strings[i]
// since the ones before are checked
for (int j = i + 1; j < size; j++) {
// no need for if ( i == j ) here
if (!strings.get(j).equals(strings.get(i)))
continue;
duplicates++;
strings.remove(j);
// decrease j because the array got re-indexed
j--;
// decrease the size of the array
size--;
} // for j
} // for i
return duplicates;
}
You could try this one liner to take a copy of the String preserving order.
List<String> list;
List<String> dedupped = new ArrayList<String>(new LinkedHashSet<String>(list));
This approach is also O(n) amortized instead of O(n^2)
Just to clarify my comment on matt b's answer, if you really want to count the number of duplicates removed, use this code:
List<String> list = new ArrayList<String>();
// list gets populated from user input...
Set<String> set = new HashSet<String>(list);
int numDuplicates = list.size() - set.size();
List<String> lst = new ArrayList<String>();
lst.add("one");
lst.add("one");
lst.add("two");
lst.add("three");
lst.add("three");
lst.add("three");
Set se =new HashSet(lst);
lst.clear();
lst = new ArrayList<String>(se);
for (Object ls : lst){
System.out.println("Resulting output---------" + ls);
}
I've been trying to use nested loops to accomplish this but I've been running into trouble because when entries get deleted, the indexing of the ArrayList gets altered and things don't work as they should
Why don't you just decrease the counter each time you delete an entry.
When you delete an entry the elements will move too:
ej:
String [] a = {"a","a","b","c" }
positions:
a[0] = "a";
a[1] = "a";
a[2] = "b";
a[3] = "c";
After you remove your first "a" the indexes are:
a[0] = "a";
a[1] = "b";
a[2] = "c";
So, you should take this into consideration and decrease the value of j ( j--) to avoid "jumping" over a value.
See this screenshot:
public Collection removeDuplicates(Collection c) {
// Returns a new collection with duplicates removed from passed collection.
Collection result = new ArrayList();
for(Object o : c) {
if (!result.contains(o)) {
result.add(o);
}
}
return result;
}
or
public void removeDuplicates(List l) {
// Removes duplicates in place from an existing list
Object last = null;
Collections.sort(l);
Iterator i = l.iterator();
while(i.hasNext()) {
Object o = i.next();
if (o.equals(last)) {
i.remove();
} else {
last = o;
}
}
}
Both untested.
Assuming you can't use a Set like you said, the easiest way of solving the problem is to use a temporary list, rather than attempting to remove the duplicates in place:
public class Duplicates {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("one");
list.add("two");
list.add("three");
list.add("three");
list.add("three");
System.out.println("Prior to removal: " +list);
System.out.println("There were " + removeDuplicates(list) + " duplicates.");
System.out.println("After removal: " + list);
}
public static int removeDuplicates(List<String> list) {
int removed = 0;
List<String> temp = new ArrayList<String>();
for(String s : list) {
if(!temp.contains(s)) {
temp.add(s);
} else {
//if the string is already in the list, then ignore it and increment the removed counter
removed++;
}
}
//put the contents of temp back in the main list
list.clear();
list.addAll(temp);
return removed;
}
}
You could do something like this, must of what people answered above is one alternative, but here's another.
for (int i = 0; i < strings.size(); i++) {
for (int j = j + 1; j > strings.size(); j++) {
if(strings.get(i) == strings.get(j)) {
strings.remove(j);
j--;
}`
}
}
return strings;
Using a set is the best option to remove the duplicates:
If you have a list of of arrays you can remove the duplicates and still retain array list features:
List<String> strings = new ArrayList<String>();
//populate the array
...
List<String> dedupped = new ArrayList<String>(new HashSet<String>(strings));
int numdups = strings.size() - dedupped.size();
if you can't use a set, sort the array (Collections.sort()) and iterate over the list, checking if the current element is equal to the previous element, if it is, remove it.
Using a set is the best option (as others suggested).
If you want to compare all elements in a list with eachother you should slightly adapt your for loops:
for(int i = 0; i < max; i++)
for(int j = i+1; j < max; j++)
This way you don't compare each element only once instead of twice. This is because the second loop start at the next element compared to the first loop.
Also when removing from a list when iterating over them (even when you use a for loop instead of an iterator), keep in mind that you reduce the size of the list. A common solution is to keep another list of items you want to delete, and then after you finished deciding which to delete, you delete them from the original list.
public ArrayList removeDuplicates(ArrayList <String> inArray)
{
ArrayList <String> outArray = new ArrayList();
boolean doAdd = true;
for (int i = 0; i < inArray.size(); i++)
{
String testString = inArray.get(i);
for (int j = 0; j < inArray.size(); j++)
{
if (i == j)
{
break;
}
else if (inArray.get(j).equals(testString))
{
doAdd = false;
break;
}
}
if (doAdd)
{
outArray.add(testString);
}
else
{
doAdd = true;
}
}
return outArray;
}
You could replace the duplicate with an empty string*, thus keeping the indexing in tact. Then after you've completed you can strip out the empty strings.
*But only if an empty string isn't valid in your implementation.
The problem you are seeing in your code is that you remove an entry during iteration, thus invalidating the iteration location.
For example:
{"a", "b", "c", "b", "b", "d"}
i j
Now you are removing strings[j].
{"a", "b", "c", "b", "d"}
i j
The inner loop ends and j is incremented.
{"a", "b", "c", "b", "d"}
i j
Only one duplicate 'b' detected...oops.
best practice in these cases is to store the locations that have to be removed, and remove them after you have finished iterating through the arraylist. (One bonus, the strings.size() call can be optimized outside of the loops by you or the compiler)
Tip, you can start iterating with j at i+1, you've already checked the 0 - i!
The inner for loop is invalid. If you delete an element, you cannot increment j, since j is now pointing at the element after the one you deleted, and you will need to inspect it.
In other words, you should use a while loop instead of a for loop, and only increment j if the elements at i and j do not match. If they do match, remove the element at j. size() will decrease by 1 and j will now be pointing at the following element, so there is no need to increase j.
Also, there is no reason to inspect all elements in the inner loop, just the ones following i, since duplicates before i have already been removed by prior iterations.
public <Foo> Entry<Integer,List<Foo>> uniqueElementList(List<Foo> listWithPossibleDuplicates) {
List<Foo> result = new ArrayList<Foo>();//...might want to pre-size here, if you have reliable info about the number of dupes
Set<Foo> found = new HashSet<Foo>(); //...again with the pre-sizing
for (Foo f : listWithPossibleDuplicates) if (found.add(f)) result.add(f);
return entryFactory(listWithPossibleDuplicates.size()-found.size(), result);
}
and then some entryFactory(Integer key, List<Foo> value) method. If you want to mutate the original list (possibly not a good idea, but whatever) instead:
public <Foo> int removeDuplicates(List<Foo> listWithPossibleDuplicates) {
int original = listWithPossibleDuplicates.size();
Iterator<Foo> iter = listWithPossibleDuplicates.iterator();
Set<Foo> found = new HashSet<Foo>();
while (iter.hasNext()) if (!found.add(iter.next())) iter.remove();
return original - found.size();
}
for your particular case using strings, you may need to deal with some additional equality constraints (e.g., are upper and lower case versions the same or different?).
EDIT: ah, this is homework. Look up Iterator/Iterable in the Java Collections framework, as well as Set, and see if you don't come to the same conclusion I offered. The generics part is just gravy.
I am bit late to join this question, but I have come with a better solution regarding the same using GENERIC type. All the above provided solutions are just a solution. They are increasing a lead to the complexity of whole runtime thread.
RemoveDuplicacy.java
We can minimize it using a technique which should do the required , at the Load Time.
Example : For suppose when you are using a arraylist of the class type as :
ArrayList<User> usersList = new ArrayList<User>();
usersList.clear();
User user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("AB");
user.setId("2"); // duplicate
usersList.add(user);
user = new User();
user.setName("C");
user.setId("4");
usersList.add(user);
user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("A");
user.setId("2"); // duplicate
usersList.add(user);
}
The Class for which is the base for the arraylist used above : User class
class User {
private String name;
private String id;
/**
* #param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* #return the id
*/
public String getId() {
return id;
}
}
Now in java there are two Overrided methods present of Object (parent) Class, which can help here in the means to serve our purpose better.They are :
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
You have to override these methods in the User class
Here is the complete code :
https://gist.github.com/4584310
Let me know if you have any queries.
You can add the list into a HashSet and then again convert that hashset into list to remove the duplicates.
public static int removeDuplicates(List<String> duplicateList){
List<String> correctedList = new ArrayList<String>();
Set<String> a = new HashSet<String>();
a.addAll(duplicateList);
correctedList.addAll(a);
return (duplicateList.size()-correctedList.size());
}
here it will return the number of duplicates. You can also use the correctList with all unique values
Below is the code to remove duplicate elements from a list without changing the order of the list,without using temporary list and without using any set variables.This code saves the memory and boosts performance.
This is a generic method which works with any kind of list.
This was the question asked in one of the interviews.
Searched in many forums for the solution but could not find one,so thought this is the correct forum to post the code.
public List<?> removeDuplicate(List<?> listWithDuplicates) {
int[] intArray = new int[listWithDuplicates.size()];
int dupCount = 1;
int arrayIndex = 0;
int prevListIndex = 0; // to save previous listIndex value from intArray
int listIndex;
for (int i = 0; i < listWithDuplicates.size(); i++) {
for (int j = i + 1; j < listWithDuplicates.size(); j++) {
if (listWithDuplicates.get(j).equals(listWithDuplicates.get(i)))
dupCount++;
if (dupCount == 2) {
intArray[arrayIndex] = j; // Saving duplicate indexes to an array
arrayIndex++;
dupCount = 1;
}
}
}
Arrays.sort(intArray);
for (int k = intArray.length - 1; k >= 0; k--) {
listIndex = intArray[k];
if (listIndex != 0 && prevListIndex != listIndex){
listWithDuplicates.remove(listIndex);
prevListIndex = listIndex;
}
}
return listWithDuplicates;
}
I have an array of strings, and I want to delete a particular string from that array. How can I do that? My code is:
private void nregexp(){
String str_nregexp = i_exp_nregexp.getText();
boolean b;
for(int i=0; i<selectedLocations.length; i++){
b= selectedLocations[i].indexOf(str_nregexp) > 0;
if(b){
String i_matches = selectedLocations[i];
........
........
}
}
}
I have to remove i_matches from selectedLocations.
I depends what you mean by "delete a particular String from an array". If you wish to remove its value, you can simply set its value to null, however if you mean actually remove that element from the array (you have an array of 5 elements and you want the result after deleting the element to be 4), this is not possible without copying the array with the item removed.
If you want this behavior, you might want to take a look at a dynamic list such as ArrayList or LinkedList
Edit: If you wanted a simple method to copy the array into an array with the String removed, you could do something like:
List<Foo> fooList = Arrays.asList(orgArray);
fooList.remove(itemToRemove);
Foo[] modifiedArray = fooList.toArray();
You will need to copy the array to a smaller array, omitting the string you don't want. If this is a common situation, you should consider using something other than an array, such as LinkedList or ArrayList.
If you really want to do it yourself, here is an example:
import java.util.Arrays;
public class DelStr {
public static String[] removeFirst(String[] array, String what) {
int idx = -1;
for (int i = 0; i < array.length; i++) {
String e = array[i];
if (e == what || (e != null && e.equals(what))) {
idx = i;
break;
}
}
if (idx < 0) {
return array;
}
String[] newarray = new String[array.length - 1];
System.arraycopy(array, 0, newarray, 0, idx);
System.arraycopy(array, idx + 1, newarray, idx, array.length - idx - 1);
return newarray;
}
public static void main(String[] args) {
String[] strings = { "A", "B", "C", "D" };
System.out.printf("Before: %s%n", Arrays.toString(strings));
System.out.printf("After: %s%n",
Arrays.toString(removeFirst(strings, "D")));
}
}
You cannot change the length of the array, after initializing an array its length is set. So you cannot delete the element directly, you can only replace it, also with null.
String[] arr = new String[10];
// fill array
...
// replace the fifth element with null
arr[4] = null;
If you want to change the length of the Array you should try a list instead:
List<String> list = new ArrayList<String>();
// fill list
...
// remove the fifth element
list.remove(4);
Could you show us your code? Why don't you use ArrayList, as it has a remove(index) and remove(object) support?
Edit: Perhaps
private void nregexp() {
String str_nregexp = i_exp_nregexp.getText();
boolean b;
List<String> list = new ArrayList<String>(Arrays.asList(selectedLocations));
for(Iterator<String> it = list.iterator(); i.hasNext();){
String e = it.next();
b = e.indexOf(str_nregexp) > 0;
// b = e.matches(str_regexp); // instead?
if(b){
String i_matches = s;
it.remove(); // we don't need it anymore
........
........
}
}
selectedLocations = list.toArray(new String[list.size()]);
}
I've reached this solution that allows you to remove all the elements that equal the removal element:
private static <T> T[] removeAll(T[] array, T element) {
if (null == array)
throw new IllegalArgumentException("null array");
if (null == element)
throw new IllegalArgumentException("null element");
T[] result = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length);
int j = 0;
for (int i = 0; i < array.length; i++) {
if (!element.equals(array[i]))
result[j++] = array[i];
}
return Arrays.copyOf(result, j);
}
I also did some benchmarking and this solution is definitely better then using Lists. Although, if performance is not a problem here, I would use Lists.
If you really need to remove only one element (the first) #kd304 has the solution.