delete and move elements in a table : java - java

private JEditorPane textArea[]= new JEditorPane[maxTabs];
I've got this table,I want to delete some elements and move the others, for example if I delete the second element, the third will be instead of the second and so on.

Depending on scenario you are interested (we remove for example element at position 1)
1) If elements should be shifted to left and last element should be set to 0 or null depending on type of array like
before [0,1,2,3,4]
after [0,2,3,4,0]
you can use
System.arraycopy(textArea, index+1, textArea, index, textArea.length-index-1);
array[array.length-1]=null;
2) when you want to replace old array with new one that wont contain selected element like
before [0,1,2,3,4]
after [0,2,3,4] //we removed element at position 1 (new array is smaller)
you can try something like this
List<JEditorPane> listCopy = new ArrayList<JEditorPane>(
Arrays.asList(textArea));
listCopy.remove(index);
textArea = listCopy.toArray(new JEditorPane[listCopy.size()]);

You can use System.arraycopy() to move chunks of arrays around: see https://stackoverflow.com/a/5536023/150001
If you can, though, consider using a Collection class like java.util.LinkedList, which is much better suited to removing and reordering elements. If you still need an array when you're done with your deletions/moves (maybe the API you're working with requires it), you can use the toArray() method.

Related

Removing elements from the beginning vs the end

In the Collection framework tutorials for the List interface, there is an interesting quote regarding performance of removal of elements from a List implementation:
For many common List implementations, such as ArrayList, the performance of removing elements from the end of the list is substantially better than that of removing elements from the beginning.
The tutorials do not go further into explaining this and I am trying to understand exactly why it might be so.
Considering an ArrayList<Integer> list as below:
In the first scenario, if we remove the last 4 elements from the end of the list, then the values of these are set to null (or equivalent). My theory is that, when a copy operation is necessary, only the elements that are not null will be copied.
In the second scenario, if we remove the first 4 elements, they would be set to null again and again only non-null elements would be copied.
So from this point of view, the performances appear to be around the same. Is there another reason why the operation is faster if performed from the end?
On the other hand, for LinkedList, the inverse appears to be true; removal from the beginning is faster, whereas removal from the end requires an almost full traversal unless a tail-pointer
is kept.
As per my understanding,
ArrayList is an array implementation of a list. So if you remove elements from the beginning of an array you need to move all the remaining elements to fill up the elements that you removed. So this is going to essentially be a O(n-1) operation.However this is not the case when you remove elements from end of the list. This will be O(1).
There is more to removing elements from the beginning of the list than just setting the elements to null. You also need to move the remaining elements to fill in the vacated locations.
It's possible to use a variable to keep track of the "beginning" of the list without moving elements, but then you will sacrifice memory efficiency because of the unused elements in the array.
In ArrayList<> removing from start is slow because entire array will have to be shifted since the add function add the elements at and if we left the start empty then we will be wasting the memory.
If we take into account big(O) notation removing from start is essentially linear time O(n) while deleting from end is constant time O(1).
While Code-Apprentice's answer is correct, I'd like to elaborate on how you can verify the behavior that every entry is moved to the left by making an index-based lookup, i.e., calling list.get(index).
add two entries
remove the first element
check the value of the first element: is it now null or the previously second element?
The code to verify:
List<String> list = new ArrayList<>();
list.add("0");
list.add("1");
list.remove(0);
String entry0 = list.get(0);
System.out.println(entry0);
You suspected that null would be printed, but "1" is printed.
This confirms that all the elements are shifted to the left.
NB. I used Strings to avoid the confusion caused by remove(int index) and remove(Object o).

ArrayList - LinkedList Clarification

Can any one tell me clearly why ?
Reading is simple in ArrayList,( we can access through its array index ), why not in linkedList
Inserting element in arrayList is tough i heard why ? easy in linkedList why ?
Deleting element in arraylist is tough why ? easy in linkedList why ?
I know some thing about arrays, but what going in linkedXXX
Thank you.
In an ArrayList, you keep an array of references in memory, that is to say, you have a memory position. When you ask for the first element of an ArrayList, you just access the memory position. When you access the 10th element, you access the memory position + 10 times the size of a reference.
In an LinkedList, you have one element, which has a reference to the next. The next one references the next, and so on. As you can see, there is no direct way of accessing the 10th element in a LinkedList without going one by one getting the next element.
So, your questions:
Inserting element in arrayList is touch i heard why ? easy in linkedList why ?
There are two problems with inserting an element into an ArrayList:
When you put an element in position 3, you need to first move every element starting at position 3 and shift them right once (3 becomes 4, 4 becomes 5, etc...) so that 3 becomes empty and you can put in your new element
If the array that backs your ArrayList is already full, you need to create a new one! This is very costly, since you need to allocate the memory again, and then copy all elements to the new array, and destroy the old one.
In a Linkedlist, on the other hand, you go to element 1, which points to 2, and then go to 2. In 2, there's a reference to the old element 3, which you temporarily store elsewhere. You replace it with a reference to your new element, and in your new element, you make next point to the old 3. This is therefore way less costly.
Deleting element in arraylist is touch why ? easy in linkedList why ?
Similar reasons as inserting. In an ArrayList, you have to shift all the elements down again, in the LinkedList, once you are at element 2, you make its next point to 4, and voila, 3 is erased.
And for completeness
ArrayLists are great if you are going to access elements in a random order, but have the problems of adding and substracting. LinkedLists are great to add and remove, but getting an element that's not the first or last takes extra cost. So there's always a trade-off!
An ArrayList is backed by an array, which can't grow or shrink, nor can elements be inserted or removed. So insertion and removal are expensive operations, since a new array has to be created and the existing values copied from one array to the other. But an array can be accessed by index, so Random Access is much faster here.
A LinkedList consists of Node Objects that have pointers (yes, I know) to each other in one direction or both. It is very cheap to remove one of these nodes or insert a new one, but to get node nr. 12345, you have to start at the beginning and walk over 12344 nodes, which means random access is very expensive here. Note: A Java LinkedList is not only a List, btw, it also implements the Queue and Deque interfaces.
I think both are equally well suited for simple iteration, but the underlying mechanism is completely different.

Adding elements into ArrayList at position larger than the current size

Currently I'm using an ArrayList to store a list of elements, whereby I will need to insert new elements at specific positions. There is a need for me to enter elements at a position larger than the current size. For e.g:
ArrayList<String> arr = new ArrayList<String>();
arr.add(3,"hi");
Now I already know there will be an OutOfBoundsException. Is there another way or another object where I can do this while still keeping the order? This is because I have methods that finds elements based on their index. For e.g.:
ArrayList<String> arr = new ArrayList<String>();
arr.add("hi");
arr.add(0,"hello");
I would expect to find "hi" at index 1 instead of index 0 now.
So in summary, short of manually inserting null into the elements in-between, is there any way to satisfy these two requirements:
Insert elements into position larger than current size
Push existing elements to the right when I insert elements in the middle of the list
I've looked at Java ArrayList add item outside current size, as well as HashMap, but HashMap doesn't satisfy my second criteria. Any help would be greatly appreciated.
P.S. Performance is not really an issue right now.
UPDATE: There have been some questions on why I have these particular requirements, it is because I'm working on operational transformation, where I'm inserting a set of operations into, say, my list (a math formula). Each operation contains a string. As I insert/delete strings into my list, I will dynamically update the unapplied operations (if necessary) through the tracking of each operation that has already been applied. My current solution now is to use a subclass of ArrayList and override some of the methods. I would certainly like to know if there is a more elegant way of doing so though.
Your requirements are contradictory:
... I will need to insert new elements at specific positions.
There is a need for me to enter elements at a position larger than the current size.
These imply that positions are stable; i.e. that an element at a given position remains at that position.
I would expect to find "hi" at index 1 instead of index 0 now.
This states that positions are not stable under some circumstances.
You really need to make up your mind which alternative you need.
If you must have stable positions, use a TreeMap or HashMap. (A TreeMap allows you to iterate the keys in order, but at the cost of more expensive insertion and lookup ... for a large collection.) If necessary, use a "position" key type that allows you to "always" generate a new key that goes between any existing pair of keys.
If you don't have to have stable positions, use an ArrayList, and deal with the case where you have to insert beyond the end position using append.
I fail to see how it is sensible for positions to be stable if you insert beyond the end, and allow instability if you insert in the middle. (Besides, the latter is going to make the former unstable eventually ...)
even you can use TreeMap for maintaining order of keys.
First and foremost, I would say use Map instead of List. I guess your problem can be solved in better way if you use Map. But in any case if you really want to do this with Arraylist
ArrayList<String> a = new ArrayList<String>(); //Create empty list
a.addAll(Arrays.asList( new String[100])); // add n number of strings, actually null . here n is 100, but you will have to decide the ideal value of this, depending upon your requirement.
a.add(7,"hello");
a.add(2,"hi");
a.add(1,"hi2");
Use Vector class to solve this issue.
Vector vector = new Vector();
vector.setSize(100);
vector.set(98, "a");
When "setSize" is set to 100 then all 100 elements gets initialized with null values.
For those who are still dealing with this, you may do it like this.
Object[] array= new Object[10];
array[0]="1";
array[3]= "3";
array[2]="2";
array[7]="7";
List<Object> list= Arrays.asList(array);
But the thing is you need to identify the total size first, this should be just a comment but I do not have much reputation to do that.

How to delete one value from, and decrease the length of, a String array

I don't understand how to decrease the length of a String array. For example, with this code:
String[][] array = new String[5][2];
array[1][0] = "what";
array[2][0] = "is";
.....
.....
array[5][0] = "?";
How can I delete array[5][0] and get array.length to be 4, not 5?
If you want to remove the array element from the end , you can also use Arrays.copyOf() since jdk 1.6+
For example:
array = Arrays.copyOf(array, 4);
It just copy the original array 's first 4 elements to a new array , so it have the same effect as deleting the array[5]
If you want to remove an element from an specified index , you can use ArrayUtils.remove() from Apache Commons Lang 3 to do it .
/**Remove the element at index 3**/
array =ArrayUtils.remove(array, 3);
You cannot delete an item from an array.
But you can create a new array with smaller size and copy the content of the old array to the new one. Then, assign the value of the reference to the new array.
Consider using java.util.List. It has a method remove().
Using arrays for such things is very time consuming. I can suggest these solutions:
1. Use one of the data structures provided by Java libraries. I'd go with HashMap since its structure allows mapping a value to a key (HashMap ) and it does the part of adding, finding and removing items. You can also use them for multi-level hashmaps if you need more than 2 columns (HashMap ) you can look that up.
2. Use a List or ArrayList structure. Make a list that contains arrays or a special structure you create to store your data.
3. (Not recommended) Go for the manual route. If you have a fixed-length array, you can shift the rows back to remove that row, and use an index to define the last row. If you have a dynamic-length array you'll need to reconstruct it each time you remove a row.

What is the best way to remove the first element from an array?

I have string array (String[]) and I need to remove the first item. How can I do that efficiently?
The size of arrays in Java cannot be changed. So, technically you cannot remove any elements from the array.
One way to simulate removing an element from the array is to create a new, smaller array, and then copy all of the elements from the original array into the new, smaller array.
String[] yourArray = Arrays.copyOfRange(oldArr, 1, oldArr.length);
However, I would not suggest the above method. You should really be using a List<String>. Lists allow you to add and remove items from any index. That would look similar to the following:
List<String> list = new ArrayList<String>(); // or LinkedList<String>();
list.add("Stuff");
// add lots of stuff
list.remove(0); // removes the first item
Simplest way is probably as follows - you basically need to construct a new array that is one element smaller, then copy the elements you want to keep to the right positions.
int n=oldArray.length-1;
String[] newArray=new String[n];
System.arraycopy(oldArray,1,newArray,0,n);
Note that if you find yourself doing this kind of operation frequently, it could be a sign that you should actually be using a different kind of data structure, e.g. a linked list. Constructing a new array every time is an O(n) operation, which could get expensive if your array is large. A linked list would give you O(1) removal of the first element.
An alternative idea is not to remove the first item at all, but just increment an integer that points to the first index that is in use. Users of the array will need to take this offset into account, but this can be an efficient approach. The Java String class actually uses this method internally when creating substrings.
You can't do it at all, let alone quickly. Arrays in Java are fixed size. Two things you could do are:
Shift every element up one, then set the last element to null.
Create a new array, then copy it.
You can use System.arraycopy for either of these. Both of these are O(n), since they copy all but 1 element.
If you will be removing the first element often, consider using LinkedList instead. You can use LinkedList.remove, which is from the Queue interface, for convenience. With LinkedList, removing the first element is O(1). In fact, removing any element is O(1) once you have a ListIterator to that position. However, accessing an arbitrary element by index is O(n).
Keep an index of the first "live" element of the array. Removing (pretending to remove) the first element then becomes an O(1) time complexity operation.
To sum up, the quick linkedlist method:
List<String> llist = new LinkedList<String>(Arrays.asList(oldArray));
llist.remove(0);
An alternative ugly method:
String[] a ={"BLAH00001","DIK-11","DIK-2","MAN5"};
String[] k=Arrays.toString(a).split(", ",2)[1].split("]")[0].split(", ");

Categories