If I have an ArrayList of String forming part of a class in Java like so:
private ArrayList<String> rssFeedURLs;
If I want to use a method in the class containing the above ArrayList, using ArrayList contains to check if a String is contained in this ArrayList, I believe I should be able to do so as follows:
if (this.rssFeedURLs.contains(rssFeedURL)) {
Where rssFeedURL is a String.
Am I right or wrong?
You are right. ArrayList.contains() tests equals(), not object identity:
returns true if and only if this list
contains at least one element e such
that (o==null ? e==null : o.equals(e))
If you got a NullPointerException, verify that you initialized your list, either in a constructor or the declaration. For example:
private List<String> rssFeedURLs = new ArrayList<String>();
Yes, that should work for Strings, but if you are worried about duplicates use a Set. This collection prevents duplicates without you having to do anything. A HashSet is OK to use, but it is unordered so if you want to preserve insertion order you use a LinkedHashSet.
You are right that it should work; perhaps you forgot to instantiate something. Does your code look something like this?
String rssFeedURL = "http://stackoverflow.com";
this.rssFeedURLS = new ArrayList<String>();
this.rssFeedURLS.add(rssFeedURL);
if(this.rssFeedURLs.contains(rssFeedURL)) {
// this code will execute
}
For reference, note that the following conditional will also execute if you append this code to the above:
String copyURL = new String(rssFeedURL);
if(this.rssFeedURLs.contains(copyURL)) {
// code will still execute because contains() checks equals()
}
Even though (rssFeedURL == copyURL) is false, rssFeedURL.equals(copyURL) is true. The contains method cares about the equals method.
Perhaps you need to post the code that caused your exception. If the above is all you have, perhaps you just failed to actually initialise the array.
Using contains here should work though.
Your question is not very clear.
What's your code exactly doing? Give more code.
What's the error you're getting?
You say you get a null-pointer. You cannot get a null pointer as a value returned by contains().
However you can get a NullPointerException if your list has not been initialized. By reading your question now, I'd say that what you show here is correct, but maybe you just didn't instantiate the list.
For this to work (to add a feed URL if it isn't already in the list):
if (!this.rssFeedURLs.contains(rssFeedURL)) {
this.rssFeedURLs.add(rssFeedUrl);
}
then this declaration would do:
private ArrayList<String> rssFeedURLs = new ArrayList<String>();
or initialize your list later on, but before trying to access its methods:
rssFeedUrls = new ArrayList<String>();
Finally... Do you really need a List? Maybe a Set would be better if you don't want duplicates. Use a LinkedHashSet if preserving the ordering matters.
Right...with strings...the moment you deviate from primitives or strings things change and you need to implement hashcode/equals to get the desired effect.
EDIT: Initialize your ArrayList<String> then attempt to add an item.
You're correct. As others said according to your comments, you probably did not initialize your ArrayList.
My point is different: you claimed that you're checking for duplicates and this is why you call the contains method. Try using HashSet. It should be more efficient - unless you need to keep the order of URLs for any reason.
Thanks to you all for answering so quickly. I could always use a set but I have the ArrayList working now. The problem was that in the constructor of the class containing the ArrayList, I was not saying:
public RSS_Feed_Miner() {
...
this.rssFeedURLs = new ArrayList<String>();
...
}
D'Oh! for a Friday afternoon.
ArrayList<String> newlyAddedTypes=new ArrayList<String>();
.....
newlyAddedTypes.add("test1");
newlyAddedTypes.add("test1");
newlyAddedTypes.add("test2");
if(newlyAddedTypes.contain("test"){
//called here
}
else{
}
Related
This is reg. a requirement where I need to remove an element from List in java. I am getting unsupported exception when I try to remove element from List. Below is the code:
String[] str_array = {"abc","def","ght"};
List<String> results = Arrays.asList(str_array);
String tobeRemovedItem="";
for(int i=0;i<results.size();i++){
if(results.get(i).equalsIgnoreCase(searchString)) {
tobeRemovedItem=results.get(i);
}
}
if(!TextUtils.isEmpty(tobeRemovedItem)) {
results.remove(tobeRemovedItem); // I am getting exception here.
}
Can anyone help me in solving this issue?
The type of list returned by Arrays.asList does not support the remove operation. Hence the exception.
You can use the java.util.ArrayList instead.
List<String> results = new ArrayList<String>(Arrays.asList(str_array));
Answered already, but now without indirect datastructure of .asList()
List<String> results = new ArrayList<>();
Collections.addAll(results, str_array);
The .asList is backed by the array, hence you can modify the original array be modifying the list. And vice versa you cannot grow or shrink the list, as then the backed array object would need to be exchanged, as arrays are fixed in java.
The size of List returned by Arrays.asList cannot be changed. Instead you can do:
List<String> results = new ArrayList<>(Arrays.asList(str_array));
In general, UnsupportedOperationException is thrown by the implementation of an interface (or a child class of a class with an abstract method), where the implementor did not want to support that particular method.
That said, to debug these issues in the future, check which implementation you're using - in this case, it's given via the Arrays.asList() method from the Android sdk. Here you can see it says that it does not support adding or removing of items to the list.
If you must add and remove items, you can wrap the call into the ArrayList implementation of List which does support such modification (as suggested by Banthar and khelwood). The constructor takes a list as input, and copies the elements inside.
Quite new to the Java language, I was wondering whether it is correct and possible to do this:
ArrayList<PeopleDetails> people_SMS = checkbox_SMS(adapter);
Where checkbox_SMS(adapter) is a method that returns type ArrayList.
Is this legitimate code, or will the people_SMS arraylist merely contain a pointer to the the returned arraylist? Will my code work, if I want to access the data from checkbox_SMS?
Thanks for the help!!
people_SMS arraylist will merely be a pointer to the the returned arraylist. If you want to create a new list that is a copy of the returned, use
ArrayList<PeopleDetails> people_SMS = new ArrayList<>(checkbox_SMS(adapter));
It can work as long as checkbox_SMS returns an instance of ArrayList<PeopleDetails>.
I was wondering whether it is correct and possible to do this:
ArrayList<PeopleDetails> people_SMS = checkbox_SMS(adapter);
That's a completely valid line If your checkbox_sms method returning a ArrayList.. And you can use it furthur
will the people_SMS arraylist merely contain a pointer to the the returned arraylist?
Yes, it is as you are initializing with returned list.
Will my code work, if I want to access the data from checkbox_SMS?
Yes, it is.
Make sure that it is not returning a null, before using it.
Yes, this is a valid code. Inside your checkbox_SMS method you should create an instance of ArrayList<PeopleDetails> and return it.
It is also possible to return null form such a method and the code will be valid too. In such cases, you should check if people_SMS is not null before using it.
Is there any way by which I can avoid using get(0) in the list iteration ?
Its going to be always risky using get(0) while iterating over a list.
I know for sure that in this list I just have one object.
(P.S. I remember my last manager always saying to me to avoid using get(0) on list iteration.)
It's not really clear what you mean by "risky" but you might consider using Guava's Iterables.getOnlyElement:
List<String> foo = getListFromSomewhere();
String bar = Iterables.getOnlyElement(foo);
This makes it clear that you expect there to be one and only one element. If you think there may be no elements, you can use the overload which allows you to specify a default value.
That way your expectations are checked when you ask for the element... but it's not obvious what else you're looking for. (You remember your last manager warning you about this - but do you remember why he warned you?)
Edit: I misuderstood the question, not realizing there was only a single item in the List. While my options still work, they aren't really necessary. However, I question the danger of using get(0) if your precondition is that there is a list with a single element.
You have a few options:
First is simply let the loop get the object for you with a for-each loop
for(Object thing : things)
Second, is convert the list into another form and access it in the appropriate manner:
Object[] thingArray = things.toArray();
for(int i = 0; i < thingArray.length; i++)
Third is to use the ListIterator
ListIterator<Object> thingIterator = things.listIterator();
while(thingIterator.hasNext())
{
Object thing = thingIterator.next();
Object objOne = list.iterator().next();
I was looking around for some elegant solution to removing null values from a List. I came across the following post, which says I can use list.removeAll(Collections.singletonList(null));
This, however, throws an UnsupportedOperationException, which I'm assuming is because removeAll() is attempting to do some mutative operation on the immutable singleton collection. Is this correct?
If this is the case, what would be a typical use of this singletonList? To represent a collection of size 1 when you're sure you don't want to actually do anything with the collection?
Thanks in advance.
It works like a charm:
List<String> list = new ArrayList<String>();
list.add("abc");
list.add(null);
list.add("def");
list.removeAll(Collections.singletonList(null));
System.out.println(list); //[abc, def]
Indeed Collections.singletonList(null) is immutable (which is unfortunately hidden in Java[1]), but the exception is thrown from your list variable. Apparently it is immutable as well, like in example below:
List<String> list = Arrays.asList("abc", null, "def");
list.removeAll(Collections.singletonList(null));
This code will throw an UnsupportedOperationException. So as you can see singletonList() is useful in this case. Use it when client code expects a read-only list (it won't modify it) but you only want to pass one element in it. singletonList() is (thread-)safe (due to immutability), fast and compact.
[1] E.g. in scala there is a separete hierarchy for mutable and immutable collections and API can choose whether it accept this or the other (or both, as they have common base interfaces)
To answer your actual question :
what would be a typical use of this singletonList? To represent a collection of size 1 when you're sure you don't want to actually do anything with the collection?
The typical use is if you have one element and want to pass it to a method that accepts a List, ie
public void registerUsers(List<User> users) {...}
User currentUser = Login Manager.getCurrentUser();
registerUsers(Collections.singletonList(currentUser));
The removeAll() is a special case for this.
Has your list been protected with
Collections.unmodifiableList(list)
Because if you have protected it and try to modify it later you get that error.
high, how do i loop through a linked list. i need to write a method find(), that returns true if a certain string is in the list
public boolean find( Stack<String> s, String key )
{
for( String item : s )
{
if( item.equals( key ) )
return true;
}
return false;
}
Typically, you have a pointer to the head of the list. You check for whether the pointed-to item matches your search string. If it does, you return true. If not, you move your pointer to the next item in the list. If you reach the end of the list, you return false.
(I'm assuming this is homework, so I won't actually write the code. If you show us some non-working code, we'll help you make it work.)
Edited to add: If you're working with a linked list, why are you passing in a stack? Anyway, the code you've posted looks like it should work. You should probably post the code you're using to set up the data and call the find method; there may be a problem there.
The error you mention sounds like maybe you aren't passing a Stack correctly; you should be able to do a foreach loop on the contents of a Stack.
There's already a "contains" method:
http://download.oracle.com/javase/6/docs/api/java/util/LinkedList.html#contains(java.lang.Object)
If your LinkedList elements are only Strings, it should work OK. Otherwise you'll need to override the 'equals' method of your model.
It sounds like you're saying that you're implementing a custom linked list implementation called Stack, and you're having looping over your list using for-each syntax. In order to use that syntax, your class needs to implements the Iterable interface. This means you will need to create an Iterator for your list as well, which will provide next(), hasNext(), and remove() methods