I have the following code sample, im pretty sure the first block should be placed in the main(), but where do I place the second block to make this Iterator example work?
List<String> myList= new ArrayList<String> ( );
Where do i place this? Would I need to create a second class?
static void printAll(ArrayList myList)
{
Iterator it = myList.iterator();
}
then there's this typical iterator pattern....is this in any way related to the second code block?
static void printAll(ArrayList myList)
{
Iterator it = myList.iterator();
Object temp;
while( it.hasNext() )
{
temp = it.next();
System.out.println( temp );
}
return;
}
It isn't clear what you want to achieve, if you are asking how to pass your ArrayList (local variable in main) to the printAll method, do something like below:
public class XYZ {
static void printAll(ArrayList myList)
{
Iterator it = myList.iterator();
Object temp;
while(it.hasNext() )
{
temp = it.next();
System.out.println( temp );
}
return;
}
public static void main(String...args){
List<String> myList= new ArrayList<String> ( );
myList.add("Hello");
myList.add("World");
printAll(myList);//passing myList to printAll
}
}
Is there a reason you're trying to use an interator?
You can do something like this, assuming you're on Java 5.
List<String> myList= new ArrayList<String> ( );
// set up list... etc.
for(String currentString : myList) {
System.out.println(currentString);
}
Iterators are only useful if you need to remove some element of the collection while traversing it (using the Iterator.remove() method). Otherwise, just use a for-each loop.
Related
I am trying to delete the elements from list1 that are in list1
package listCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Arry2List {
public static void main(String[] args) {
String[] s = {"INDIA" ,"JAPAN","THAILAND","MALAYSIA"};
ArrayList<String> list1= new ArrayList<String>();
String[] s1 = {"THAILAND","MALAYSIA"};
ArrayList<String> list2= new ArrayList<String>();
for(String temp : s)
{
list1.add(temp);
}
for(String temp : s1)
{
list2.add(temp);
}
//removing elements from list1 that are in list2
System.out.println("In list1 **************");
for (String t : list1)
{
System.out.println(t);
}
System.out.println("In list2 **************");
for (String t1 : list2)
{
System.out.println(t1);
}
//editlist(list1,list2);
Iterator<String> i=list1.iterator();
while( i.hasNext() )
{
if ( list2.contains( i.hasNext() ) )
{
i.remove();
}
}
System.out.println("In list1 again **************");
for(int i1 =0;i1<list1.size();i1++)
{
System.out.println(list1.get(i1));
}
}
}
Output should be INDIA,JAPAN.
List1 should contain only those elements which are not in the list2.
I am a beginner to Core Java and trying to learn collections.
In the loop that checks the element using List.contains(), you're passing a boolean (i.hasNext() returns whether the iterator has more elements) instead of the element. This causes the loop to run infinitely because you never call Iterator.next() to get the next element. You should use:
if (list2.contains(i.next())) {
instead of
if (list2.contains(i.hasNext())) {
It's better practice to also save the next element in a variable for re-usability:
while (i.hasNext()) {
String element = i.next();
if (list2.contains(element)) {
i.remove();
}
}
There is a built-in method to do that:
list1.removeAll(list2)
[EDIT]
You can create the lists easier using Arrays.asList:
List<String> list1 = new ArrayList<String>(Arrays.asList("INDIA", "JAPAN", "THAILAND", "MALAYSIA"));
List<String> list2 = Arrays.asList("THAILAND", "MALAYSIA");
list1.removeAll(list2);
[EDIT2]
The Arrays.asList produces unmodifiable list, so we have to use it to initialize a modifiable one.
[EDIT3]
Your code doesn't work because you don't advance the iterator. i.hasNext() only checks if there is a next element. It returns true or false, not the element itself. Here is how to fix this:
while (i.hasNext()) {
if (list2.contains(i.next())) {
i.remove();
}
}
You can also iterate over the list2 elements and remove them from list1:
for (String el : list2) {
list1.remove(el);
}
I have an array list which when populated has a key and a value I want to know if there is a way of splitting it on repeating keys for example my current data is like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom, RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave, RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
I want it to come out more like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom]
[RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave]
[RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
Is there a way to split it on say role id or am I going about this the wrong way?
You can try by using HashMap
private static class MyItemHashMap extends HashMap {
public Item add(Item item) {
get(item).add(item);
return item;
}
public List get(Item key) {
List list = (List) get(createItemKey((Item) key));
return list == null ? createItemEntry((Item) key) : list;
}
private List createItemEntry(Item item) {
List list = new ArrayList();
put(createItemKey(item), list);
return list;
}
private Object createItemKey(Item item) {
return item.getSplitterProperty();
}
}
public static void main(String[] args) {
MyItemHashMap itemMapped = new MyItemHashMap();
List items = Arrays.asList(new Object[]{new Item("A"), new Item("B"),
new Item("C")});
for (Iterator iter = items.iterator(); iter.hasNext();) {
Item item = (Item) iter.next();
itemMapped.add(item);
}
}
If it is an ArrayList, there is no built-in function to split data like this; you will have to do it manually. If you know the number of consecutive fields that make a single structure, this shouldn't be too hard; something like this:
// 6 because there are 6 fields
for (int i = 0; i < arrayList.size(); i = i + 6) {
List thisList = arrayList.subList(i, i + 5);
// ... Now do whatever you want with thisList - it contains one structure.
}
If the number of fields can change then you'll have to do something a little more dynamic and loop through looking for a RoleID field, for example.
I'd use a HashMap to seperate the data instead of one long ArrayList ( you shouldn't have stored the data like this in the first instance )
HashMap<String,ArrayList<String>> hm = new HashMap<String,ArrayList<String>>;
// For each list:
ArrayList<String> arr = new ArrayList<String>;
arr.add("each element");
hm.put("RoleID_123.0", arr);
This way you will end up with a three dimensional structure with a key ( "RoleID..." ) pointing to its child elements.
Try this
String[] str=new String[]{"RoleID_123.0", "UserHandel_tom", "Password_12345.0", "prevPassword_null", "userCaption_thomas", "Email_tom#tom.tom", "RoleID_124.0", "UserHandel_dave", "Password_ghadf", "prevPassword_sdfsd", "userCaption_david", "Email_dave#dave.dave", "RoleID_125.0", "UserHandel_trevor", "Password_tre", "prevPassword_null", "userCaption_trev", "Email_trev#trev.trev"};
List<String> list=new ArrayList<>(Arrays.asList(str));
List<String> subList=list.subList(0,5);
You can try something similar to this
If you feel like taking a Linq-ee Libraried approach, this is about as good as it gets, and it requires use of a couple delegate objects:
import static com.google.common.collect.Collections2.filter;
import static com.google.common.collect.Collections2.transform;
//...
final List<String> yourList = //...
final int RECORD_LENGTH = 6;
Collection<String> roleIdValues = filter(yourList, new Predicate<String>() {
public boolean apply(#Nullable String input) {
return input != null && input.startsWith("RoleID");
}
});
Collection<Collection<String>> splitRecords = transform(roleIdValues, new Function<String, Collection<String>>() {
#Nullable public Collection<String> apply(#Nullable String input) {
return yourList.subList(yourList.indexOf(input), RECORD_LENGTH);
}
});
If Oracle had delivered Java 8 on time you would be able to do this in a way more slick manor. Ironically the reason you cant was provided by the same people providing the guava library
public class ArrayListTest {
public static void main(String[] args) {
ArrayList al=new ArrayList();
al.add("");
al.add("name");
al.add("");
al.add("");
al.add(4, "asd");
System.out.println(al);
}
}
o/p [, name, , , asd]
desire O/p [name,asd]
You can use removeAll(Collection<?> c) :
Removes all of this collection's elements that are also contained in
the specified collection
al.removeAll(Arrays.asList(null,""));
This will remove all elements that are null or equals to "" in your List.
Output :
[name, asd]
You can remove an object by value.
while(al.remove(""));
Iterate over the list, read each value, compare it to an empty string "" and if it is that, remove it:
Iterator it = al.iterator();
while(it.hasNext()) {
//pick up the value
String value= (String)it.next();
//if it's empty string
if ("".equals(value)) {
//call remove on the iterator, it will indeed remove it
it.remove();
}
}
Another option is to call List's remove() method while there are empty strings in the list:
while(list.contains("")) {
list.remove("");
}
List<String> al=new ArrayList<String>();
...................
for(Iterator<String> it = al.iterator(); it.hasNext();) {
String elem = it.next();
if ("".equals(elem)) {
it.remove();
}
}
I do not comment this code. You should study from it yourself. Please pay attention on all details.
I am having trouble using Iterator in java.
it=myHash.iterator();
while (it.hasNext())
if (it.next() satisfying something)
do something
while (it.hasNext())
if (it.next() satisfying something)
it.remove();
I am trying to iterate hashset twice, and the first loop making it.hasNext() return false. How to i resolve this?
I tried even adding the edit as you guys suggested, still not working...
You're reusing the same iterator - and that's been invalidated by adding new items to the set.
You should call iterator() again on the set:
it = set.iterator();
You can't reset the existing iterator
EDIT: Here's some sample code which shows this working:
import java.util.*;
public class Test {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("food");
set.add("bad");
set.add("hungry");
set.add("neighbour");
Iterator<String> it = set.iterator();
// Remove any string longer than 4
while (it.hasNext())
{
if (it.next().length() > 4)
{
it.remove();
}
}
set.add("new long text");
set.add("x");
// Remove any string shorter than 4
it = set.iterator();
while (it.hasNext())
{
if (it.next().length() < 4)
{
it.remove();
}
}
// Dump the results
for (String x : set)
{
System.out.println(x);
}
}
}
This gives the results "new long text" and "food".
Ideally, what you are looking for is a reset operation on an Iterator. Iterators are meant to be unidirectional and one-time use, as such they don't have support for reset in Java.
You can either get hold of a new Iterator instance or use ListIterator interface which allows you to look backwards using previous().
Edit:
You are using remove() on the iterator which is also removing elements from the original set. In such a case you should consider making a copy of the set since you want to iterate over the elements all over again:
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
public class IteratorSnippet {
public static void main(String[] args) {
final HashSet<Integer> myHash = new HashSet<Integer>();
myHash.addAll(Arrays.asList(1, 2, 3, 4, 5));
// make copy before using iterator with remove
final HashSet<Integer> myHash2 = new HashSet<Integer>(myHash);
Iterator<Integer> it = myHash.iterator();
System.out.println("First go...");
while (it.hasNext()) {
System.out.println(it.next());
it.remove();
}
it = myHash2.iterator();
System.out.println("Second go...");
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
I want to remove strings of length 5 from a set, but it keeps outputting the set itself.
public void remove5()
{
Set<String> newSet = new HashSet<String>();
newSet.add("hello");
newSet.add("my");
newSet.add("name");
newSet.add("is");
newSet.add("nonsense");
for(String word: newSet)
{
if(word.length()==5)
{
newSet.remove(word); // Doesn't Help - throws an error Exception in thread "main" java.util.ConcurrentModificationException
}
}
System.out.println(newSet);
}
I want the output to be:
my
name
is
nonsense
(hello was removed because it's 5 characters)
But I get this everytime:
hello
my
name
is
nonsense
Can you please help?
Iterator<String> it= newStr.iterator();
while(it.hasNext()) { // iterate
String word = it.next();
if(word.length() == 5) { // predicate
it.remove(); // remove from set through iterator - action
}
}
For actually modifying your set, you need to do something like this:
Iterator<String> iter = newSet.iterator();
while (iter.hasNext())
if (iter.next().length() == 5)
iter.remove();
Since Strings are immutable, you can't modify the ones that were already added to the set, and anyway, even if you could modify them in-place, replacing them by "" would not remove them from the set.
As other suggested you cannot change a String reason being, Code snippet:
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class TestString {
public void remove5() {
Set<String> newSet = new HashSet<String>();
newSet.add("hello");
newSet.add("my");
newSet.add("name");
newSet.add("is");
newSet.add("nonsense");
for (Iterator<String> iter = newSet.iterator(); iter.hasNext();) {
if (iter.next().length() == 5) {
iter.remove();
}
}
System.out.println(newSet);
}
public static void main(String[] args) {
new TestString().remove5();
}
}
If you iterate over the set and in the loop you remove the object, it will throw you ConcurrentModificationExceptionas HastSet iterator is a fail fast Iterator.
When you find a string of length 5, you need to remove it from the set:
newSet.remove(word);
As it is, you appear to be trying to change word to an empty string, but strings are immutable. What your call actually does is return an empty string.
Strings are immutable, changes made to the String word or any other String will not reflect in the string of Set
add
if(word.length()==5)
{
word.replaceAll(word, "");
newSet.remove(word);
}
you can refer to this function of HashSet
remove(Object o)
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashSet.html
Strings are immutable in Java, that means when you call word.replaceAll(word,""), it returns the String "" (which you aren't assigning to anything). The word doesn't change and the Set is still pointing to the old value of word. You need to remove word from the Set itself.
int i = 0;
Set<String> newSet = new HashSet<String>();
newSet.add("hello");
newSet.add("my");
newSet.add("name");
newSet.add("is");
newSet.add("nonsense");
for(String word: newSet)
{
if(word.length()==5)
{
newSet.remove(i);
}
i++;
}