Can someone show me how to remove an object from an array. But here's the catch (well for me), the array is something like this
member[0] = new Member("John Cena" , "p000001");
I want to be able to search a name, then when that is detected, to be able to remove. is it possible?
public static void remove(){
System.out.println("Name: ");
String removeName = input.next();
System.out.println("ID: ");
String removeID = input.next();
for(int i = 0; i < member.length; i++){
//not sure if this is the right direction
}
}
EDIT: Cannot use ArrayList or list because of requirements in an Assignment. Would have used it since it is easier but can't.
You can either use an ArrayList (or better yet, ArrayList<Member>), which you can populate with members, and then use the indexOf method to search through.
Alternatively, if you have to or would rather use arrays, create a loop like you have that iterates through each index of your members array. The only tricky part is removal requires that you remove it from the array, and then shift each index in front of it down so that the blank space is remove.
In other words, you need to delete index i and use a loop so that you move the member at i + 1 down to i, member i + 2 moves down to i + 1, and so on until you reach the end of the array.
With all that being said, I'd encourage use of the ArrayList. It does all of the operations I just described for you and makes matters a lot easier.
Arrays are fixed-size. This means that the best you can do for an object array is set the value to null. If you want to remove it completely, you'll want to use ArrayList instead. In that case,
ArrayList<Member> members = new ArrayList<Member>();
for (int i = members.length-1; i>=0; i--) {
if (members.get(i).getName().equals(toRemove)) {
members.remove(i);
}
}
Sorry for my previous wrong answer. This should be the correct way of removing your Members
List<Member> l = new ArrayList<>(Arrays.asList(member));
for (Iterator<Member> iter = l.listIterator(); iter.hasNext(); ) {
Member a = iter.next();
if ( (a.getId() == removeID) || (removeName.equals(a.getName)) ) {
iter.remove();
}
}
Member[] newMembers = l.toArray(new Member[l.size()]);
PS: Please get removeID like this;
int removeID = input.nextInt();
It's a bit wonky that you have to use an array, because:
You can't truly guarantee that there isn't going to be more than one person with the same name, since the array doesn't guarantee unique entries.
Arrays don't dynamically resize, leaving you to have to do that yourself.
It can still be done though. Here's an example using Java 8's Stream API.
Let's assume you're looking for a Member with the same name and ID. Then, you're going to want to filter out any elements that are not that entry, collect them to a List, and then turn that List into an array.
So the result would be:
member = Arrays.stream(member)
.filter(m -> removeName.equals(m.getName())
&& removeID.equals(m.getID()))
.collect(Collectors.toList())
.toArray(new Member[0]);
Related
public ArrayList<String> getWords()
{
int size1 = lines.size();
int size2 = 0;
int counter3 = 0;
ArrayList<Integer> checkthewords;
for (int x = 0; x < size1; x++)
{
size2 = lines.get(x).substring(x).length();
for (int y = 0; y < size2; y++)
{
if (Character.isLetter(charAt(((lines.get(x)).indexOf(x, z + x)))))
{
words.set(z, lines.get(x).substring(x,z + 1));
}
else
{
checkthewords.set(counter3, words);
counter3++;
}
if (checkthewords.get(x).equals(checkthewords.get(counter3)))
{
}
}
}
return words;
}
The method above is a called getWords(). I am trying to get a word from a file and store it in the arrayList checkthewords. I want to make sure that a word is not going to be stored in the arrayList checkthewords more than once.
I have the if statement:
if (Character.isLetter(charAt(((lines.get(x)).indexOf(x, z + x)))))
But, don't know where to go from there.
I'm pretty sure your code won't run at the moment. You are doing some strange things in there and I don't really understand it.
Try to approach this one step at a time.
The first step is to get the word from the file. Make sure you can parse the line and extract the word you want.
Then you need to check if the word exists in your checkthewords list. If it doesn't exist, add it. You can use the contains method provided by List to see if the list contains something.
if(!checkthewords.contains(word)) {
// it's not in the list yet, add it
checkthewords.add(word);
}
Also when you create your checkthewords list, you don't initialise it (so it's null):
ArrayList<String> checkthewords;
should be:
ArrayList<String> checkthewords = new ArrayList<String>();
And you shouldn't use checkthewords.set() like that. set is used to replace an existing element, not to add a new element. You could easily be setting an element that doesn't exist yet and throw an ArrayIndexOutOfBoundsException. Use checkthewords.add(word) to add something to your list.
See the ArrayList documentation.
set(int index, E element)
Replaces the element at the specified position in this list with the specified element.
It seems like you're overthinking this. Keep it simple. :)
You should use Set in Java to store elements when duplicates are not allowed.
A collection that contains no duplicate elements.
If you want to retain insertion order as well then use LinkedHashSet which is Hash table and linked list implementation of the Set interface, with predictable iteration order.
Kindly refer to below tutorials to understand application of Set in java.
Tutorial 1
Tutorial 2
Tutorial 3
See Also-:
HashSet vs TreeSet vs LinkedHashSet
HashSet vs LinkedHashSet
I am looping through a list A to find X. Then, if X has been found, it is stored into list B. After this, I want to delete X from list A. As speed is an important issue for my application, I want to delete X from A without looping through A. This should be possible as I already know the location of X in A (I found its position in the first line). How can I do this?
for(int i = 0; i<n; i++) {
Object X = methodToGetObjectXFromA();
B.add(X);
A.remove(X); // But this part is time consuming, as I unnecessarily loop through A
}
Thanks!
Instead of returning the object from yhe method, you can return its index and then remove by index:
int idx = methodToGetObjectIndexFromA();
Object X = A.remove(idx); // But this part is time consuming, as I unnecessarily loop through A
B.add(X);
However, note that the remove method may be still slow due to potential move of the array elements.
You can use an iterator, and if performance is an issue is better you use a LinkedList for the list you want to remove from:
public static void main(String[] args) {
List<Integer> aList = new LinkedList<>();
List<Integer> bList = new ArrayList<>();
aList.add(1);
aList.add(2);
aList.add(3);
int value;
Iterator<Integer> iter = aList.iterator();
while (iter.hasNext()) {
value = iter.next().intValue();
if (value == 3) {
bList.add(value);
iter.remove();
}
}
System.out.println(aList.toString()); //[1, 2]
System.out.println(bList.toString()); //[3]
}
If you stored all the objects to remove in a second collection, you may use ArrayList#removeAll(Collection)
Removes from this list all of its elements that are contained in the
specified collection.
Parameters:
c collection containing elements to be removed from this list
In this case, just do
A.removeAll(B);
When exiting your loop.
Addition
It calls ArrayList#batchRemove which will use a loop to remove the objects but you do not have to do it yourself.
I am having some trouble with removing values that do not match a given value. At the moment I am copying over values to a new list and trying to clear the original list - but this is inefficient.
This is my code:
int size = list.size();
ArrayList<String> newList;
int count = 0;
newList = new ArrayList<>();
for (int i=0; i<list.size(); i++){
if(list.get(i).getForename().equals(forename)){
newList.add(i, list);
}
}
list.clear();
Is there a way where I can just remove an item in the arraylist if it does NOT match the name?
EDIT:
It works but then I might need a copy, as if I select a another name from the dropdown it will be referring to the old one
Thanks
A first thought would be to iterate on the list and as soon as you find an item not matching the value, you remove it. But it will create a Concurrent modification exception, as you iterate on list while trying to remove elements in it.
An other, still not efficient would be to iterate on the list, keep track of the indexes to remove, and after iterating on the list, remove them.
ArrayList<Integer> indexList = new ArrayList<Integer>();
for(int i = 0; i<list.size(); i++){
if(!list.get(i).getForename().equals(forename)){
indexList.add(i);
}
for(Integer index : indexList){
list.remove(index);
}
indexList.clear();
Please not that this is not really efficient too, but maybe you were looking for a way to delete from the same list.
A simple solution is
while (list.contains(value)) {
list.remove(list.indexOf(value));
}
Depending on what you want, you might want to use streams instead (seems to be what you actually want, since you don't really seem to want to delete elements in your list):
newList = list.stream()
.filter(e -> getForename().equals(forename))
.collect(Collectors.toList());
or to perform your action what you might want to do:
list.stream()
.filter(e -> getForename().equals(forename))
.forEach(person -> doStuff(person));
Another way would be using iterators to avoid conflicts with modifications during iteration:
ListIterator iterator = list.listIterator();
while(iterator.hasNext()){
if(!iterator.getNext().getForename().equals(forename))
iterator.remove();
}
EDIT: Since OP can't use lambdas and streams (because of Java-version), here is what nearly happens for the second stream (the forEach). I am not using the proper interfaces, since OP can't do so either. The difference to streams is, that they also might split this into several threads and hence would be faster (especially on multi-core processors and big lists):
interface Consumer<T>{ //this is normally given by the JAVA 8 API (which has one more default method)
void accept(T t);
}
Consumer<YourObject> doIt = new Consumer<YourObject>(){ //This is what the lambda expression actually does
#Override
public void accept(YourObject e) {
doStuff(e);
}
};
for(YourObject element : list){ //since JAVA 1.5. Alternativ your old for-loop with element=list.get(i);
if(!element.getForename().equals(forename)) //the filter written in easy
continue;
doIt.accept(element); //You could also use a method or expressions instead in this context.
//doStuff(element); //What actually the upper stream does.
}
You might want to look at the oracle tutorial (this chapter) to get a feeling, when this design is appropriate https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html (I have a strong feeling, you might want to use it).
Assuming your List contains String objects the following should be what you are looking for:
for (Iterator<String> it = list.iterator(); it.hasNext()){
String foreName = it.next();
if(forName != null && foreName.equals(forename)){
it.remove();
}
}
try
for (int i=0; i<list.size();){
if(!list.get(i).getForename().equals(forename)){
list.remove(i);
}
else {
i++;
}
}
I have a list and a Object as bellow
List<MyObj> myList;
public class MyObjextends
{
String parameter1;
public String getParameter1()
{
return parameter1;
}
}
I need an efficient way to get the count of myList based on the value of parameter1 in the object without going through a for loop as bellow
int count = 0;
for( MyObj obj: myList)
{
if( obj.getParameter1().equals( "Somet_Text") )
{
count++;
}
}
Can someone please tell me how to do this?
Use a Map from parameter1 to List of MyObj and then you can use the size of map.get("Some_Text")
You could wrap the list up in a class which also has a HashMap<String, List<MyObj>>. Only allow access to the list via methods which also control the hash map. Whenever an item is added to the list, it should also be added to the hash map.
if stay with List structure, you have to do it with loop. if you don't do it, the api you used will do it any way.
If this is the main problem you want to solve, you can consider to use MultiMap Structure. Like guava's ListMultimap<String, MyObj>.
In fact it is something like map<String, List<MyObj>>
I dont understand why you would not use a for loop to iterate List, Even if efficiency is a consideration, it would not matter at all practically. But even then if you have something against for, use the iterator for list
ListIterator<MyObj> it=myList.listIterator();
int count = 0;
while(it.hasNext()){
if( it.next().getParameter1().equals( "Somet_Text") )
{
count++;
}
}
Also looking at the source for ListIterator.next() , it does not use for loop too, just if it makes any difference
public E More ...next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
But note that it uses if statement and increments cursor to traverse the list, which again would be something like a for loop.
You don't have a real reason to not wanting search in a ordered array as interface List is with a loop. The big O notation of this loop would be O(N) which is exactly what is pretended to be.
If you have to process data from a huge array of inputs, I would recommend pre-process the information by discarding the objects with the values you don't want and create the array with the values that you really need.
The Map solutions commented won't solve your problem neither, as one rule of construction is that no repeated values are allowed, which is exactly what you want to measure.
How does one iterate through a list datastructure using indices. For example consider a sentence in form a list with each element being a word. Can I step through each word using the index? Something like this --
// sentence defined something like this - List<String>
int size = sentence.size();
for (int i=0; i<size-1; i++)
{
System.out.println(sentence[i] + " " + sentence[i+1]);
}
ofcourse the above code doesn't work but is it possible to do something on those lines? As you can see, I want to access the two consecutive elements and using iterators, it starts becoming really messy.
You can use the get(i) method instead of [i]:
for (int i=0; i<size-1; i++) {
System.out.println(sentence.get(i) + " " + sentence.get(i+1));
}
List instances are not the same as arrays. They have specific methods for obtaining items at certain indexes. Try this:
// sentence defined something like this - List<String>
int size = sentence.size();
for (int i=0; i<size-1; i++)
{
System.out.println(sentence.get(i) + " " + sentence.get(i + 1));
}
Now if you had an array (e.g. String[] sentence = new String[]{"hello", "there"}), what you had would work fine.
As a side note, Java has a for-each loop that can be used on both arrays and Lists:
for (String s : sentence) {
// do something
}
Of course, this can't be used in your case because you're accessing elements at multiple indexes in each iteration of your loop - but it's important to know that something like this exists.
The x[i] expression syntax in Java can only be used for arrays. Nothing else.
As other answers have stated, the way to step through the elements of a Java list using indices is to use List.get(int). However, there is an important performance issue that needs to be considered when you do this.
The issue is that the cost of a get(int) call depends on what List implementation class you use:
For an ArrayList (or a Vector) the get(int) operation on a list of length N is O(1). That means that it does not depend on the list length, and in fact it is cheap: only a bit more expensive than an someArray[i].
For a LinkedList, the get(int) operation on a list has to step through the list from the beginning until it reaches the position you asked for. If the list length is N, then the average cost of get(int) (assuming a random position in the list) is O(N); i.e. it is proportional to the list length. If the length is long, then that will be expensive.
By contrast, if you use an Iterator (explicitly, or implicitly by using the for (E e : l) syntax), getting each element will be O(1) for all of the list implementations in java.util and java.util.concurrent (ignoring multi-threading issues such as heavy contention).
Having said that, there are some cases where iterators don't work, and the application needs to use indices.
You can also use Iterator in this case for ex:
first of all put ur elements on arraylist and try to use Iterator like this:
ArrayList arrayList = new ArrayList();
Iterator itr = arrayList.iterator();
while(itr.hasNext())
{
System.out.println(itr.next()); // Print out the elements from arraylist
}
You can process consecutive pairs of values from a list without using indices. Here's one way:
private void processWordsInSentence(List<String> sentence) {
Iterator<String> it = sentence.iterator();
if (it.hasNext()) {
String previous = it.next();
while(it.hasNext()) {
String current = it.next();
// use previous and current values, e.g.
System.out.println(previous + " " + current);
previous = current;
}
}
}
Why would you want to use something like this instead of sentence.get(index)? I would offer a couple of reasons:
In your sample, your processing is really concerned with consecutive
values from the list, not their positions. So there's no "value add"
to having to fiddle with the index explicitly.
Remember that List<T> is an interface with multiple
implementations. ArrayList<T> performs .get(index) in constant
time, but that same call on a LinkedList<T> requires time
proportional to the value of index. So there could be a real performance
consideration.
The processWordsInSentence implementation above does have to deal explicitly with the case of lists with less than two elements. The loop inside the guarding if can be written with a for statement, to separate traversal from processing the actual data a bit more aggressively, if you prefer that style.
private void processWordsInSentence(List<String> sentence) {
Iterator<String> it = sentence.iterator();
if (it.hasNext()) {
for (
String previous = it.next(), current = null;
it.hasNext();
previous = current
) {
// use previous and current values, e.g.
System.out.println(previous + " " + current);
}
}
}
Try this simple code :
List mobileSoftwares = new ArrayList();
mobileSoftwares.add("Android");
mobileSoftwares.add("IOS");
mobileSoftwares.add("Blackberry");
int size = mobileSoftwares.size();
for (int i = 0; i < size - 1; i++)
{
System.out.println(mobileSoftwares.get(i));
}