If I have a queue with strings as values How would I print all the values I was using:
System.out.println(queue.elements().toString().);
But it prints java objects...?
Do I have to use a loop to print values of queue?
Yes, you will need to use a loop however the loop can be simple like.
for(String s : queue) {
System.out.println(s.toString());
}
Actually, as long as it implements Iterable you should be able to do this type of foreach loop.
I don't understand your question. You say you want to print strings, and then after some code that doesn't compile, you say, "But it prints java objects...?" Strings are Java objects.
import java.util.*;
public class Foo {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<String>(); // create queue
for (String name : args) queue.add(name); // add strings to queue
System.out.println(queue); // print entire queue at once
for (String s : queue) System.out.println(s); // print each separately
}
}
Run with e.g., java Foo apple banana pear. The output is:
[apple, banana, pear]
apple
banana
pear
If the problem is that you are getting output like this:
[MyObject#498b5a73, MyObject#5bdf59bd, MyObject#247cb66a]
MyObject#498b5a73
MyObject#5bdf59bd
MyObject#247cb66a
Then your Queue does not actually hold Strings, and you have forgotten to override the toString() method in your class:
#Override public String toString() {
return firstName + " " + lastName + ", " + quest + ", " + favoriteColor;
}
There is no need to use a loop, unless you don't [like, this, output, format].
The answer depends on the type of queue.
If it is a Queue or Deque, then your code won't compile, because these interfaces don't define an elements() method. This applies to most of the classes that implement Collection.
If it is a Vector, then the elements() returns an Enumeration, and you have to use a loop to pull the values from it.
My advice would be:
Stop using Vector ... unless you have no choice. Vector is a legacy class. Use one of the implementations of Queue or Deque instead.
Whether or not you use Vector, use queue.toString() rather than queue.elements().toString() to render the queue contents as a String. The toString() method is defined as rendering the elements of the collection for all of the standard collection classes.
Try this:
Enumeration e = queue.elements();
while ( e.hasMoreElements() )
System.out.println( e.nextElement() );
Look at Joiner in guava.
System.out.println(Joiner.on("\n").join(queue.elememts()));
try this
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Main {
public static void main(String[] args) {
Queue myQueue = new LinkedList();
myQueue.add("A");
myQueue.add("B");
myQueue.add("C");
myQueue.add("D");
List<String> myList = new ArrayList<String>(myQueue);
for (Object theFruit : myList)
System.out.println(theFruit);
}
}
Java 1.8+ solution:
queue.forEach(System.out::println);
Related
I have a TestNG assertion which may occasionally fail due to the state of the object asserted (ArrayList element), and when it does, I would like to display this state.
I created an example which will fail in runtime, to illustrate the concept
import static org.testng.Assert.assertEquals;
#Test
public void sandbox() {
ArrayList<Integer> arr = new ArrayList<>();
assertEquals(arr.size(), 0, "The problem is: " + arr.get(0).toString());
}
I expected the assertion to pass and it will, when I remove the third argument (message). I see it's not a TestNG issue as execution is not stepping in the statement, but rather fails directly at this step with
at java.util.ArrayList.rangeCheck(ArrayList.java:657)
at java.util.ArrayList.get(ArrayList.java:433)
What's the best approach here? I am thinking of a method which will take care of the exception, but perhaps there are better known ways.
Thanks
Below should work:
import static org.testng.Assert.assertEquals;
#Test
public void sandbox() {
ArrayList<Integer> arr = new ArrayList<>();
assertEquals(arr.size(), 0, "The problem is: " + arr);
}
This is more practical as well, because if list is not empty it will print all values from the list instead of the first.
There is no other pretty way of doing it since all your arguments are passed at once to the callee, i.e. your method, so that the arr.get(0) must have been evaluated.
You may simply call for the next() element only if there is one using the Iterator over your collection:
#Test
public void sandbox() {
ArrayList<Integer> arr = new ArrayList<>();
Iterator<Integer> it = arr.iterator();
assertEquals(arr.size(), 0, "The problem is: " + (it.hasNext() ? iterator.next() : ""));
}
According to JDK docs for HashSet, remove() :
removes an element e such that (o==null ? e==null : o.equals(e)), if
this set contains such an element.
Well, here is a tiny bit of code that proves otherwise. The Set points definitely contains my point, as evidenced by equals(), and yet, remove() mysteriously fails to remove it. The trouble seems to be somehow due to the change of value of point.x (line 4 of main()). Omitting this makes everything behave as expected.
Note that the following behaves normally if points is an ArrayList rather than a HashSet.
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.HashSet;
public class RemoveTest2 {
public static void main(final String[] args) {
final Collection<Point2D.Double> points = new HashSet<Point2D.Double>();
final Point2D.Double point = new Point2D.Double();
points.add(point);
point.x++;
// make sure that points definitely contains the point we are trying to remove...
for (final Point2D.Double p : points) {
if (point.equals(p)) {
System.out.println("points definitely contains " + point);
System.out.println(point.hashCode() + " == " + p.hashCode());
}
}
if (!points.remove(point)) {
System.out.println("and yet... failed to remove " + point);
}
System.out.println("points cointains " + points.size());
}
}
The spec seems painfully clear... Please, somebody explain to me what I am missing here.
The problem is you change the hashcode of an object after using it, so the Hashset cannot get the existing object using the new hashcode (as it is stored using old hashcode).
When changing such fields, you need to first remove this object before changing it, than store it again.
Take a look at this
Very often when writing tests I've to check if two collections have the same contents and sometimes even if they have the same order. So I endlessly end up doing the same thing:
assertEquals(collection1.size(), collection2.size());
for (ItemType item : collection1){
if (!collection2.contains(item)) fail(); //This depends on the collection
}
//some more code is required to test ordering
Do you know of a good way to end this torment using some standard library?
Better use equals() method, because if you use containsAll then for two lists that have same elements can be equal although there elements are in different order. So using containsAll is not good way to compare List
Here is a demo
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class TwoButtons {
public static void main(String[] args){
Collection<Integer> c1 = new ArrayList<>(Arrays.asList(1,2,3));
Collection<Integer> c2 = new ArrayList<>(Arrays.asList(3,2,1));
System.out.println("equals " + c1.equals(c2));
System.out.println("containsAll " + c1.containsAll(c2));
}
}
output
equals false
containsAll true
You can do use this as a condition
collection1.size()==collection2.size() && collection1.containsAll(collection2)
Here you are checking that both the collections are of same size as well as the have all the elements.
As per the comments by joachim-isaksson
you can do this but will not be efficient.
collection1.containsAll(collection2) && collection2.containsAll(collection1)
You should use
ReflextionAsserter
I've below code:
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class IteratorExample {
public static void main(String[] args) {
List<String> listnames = new ArrayList<String>();
listnames.add("Tom");
listnames.add("Finn");
listnames.add("Harry");
ListIterator<String> iteratorNames = listnames.listIterator();
while (iteratorNames.hasNext()) {
System.out.println(iteratorNames);
}
}
}
When I execute, I am getting strange output like below(which differs everytime when I run the program):
java.util.ArrayList$ListItr#a200d0c
java.util.ArrayList$ListItr#a200d0c
java.util.ArrayList$ListItr#a200d0c
java.util.ArrayList$ListItr#a200d0c
java.util.ArrayList$ListItr#a200d0c
Also the program is running infinitely.
Why it is not printing the list values?
You're looking at the iterator itself.
use
iteratorNames.next()
to get the next item.
Change the below line:
System.out.println(iteratorNames);
To:
System.out.println(iteratorNames.next());
I am getting strange output like below
It's just printing the memory adress of the object using the toString() default implementation of the object class.
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
Also the program is running infinitely.
As other answers stated, you have to use next()(i.e System.out.println(iteratorNames.next());) for two reasons :
It allows you to get the element in the list while iterating it
It advances the cursor position of the iterator
That's why your program runs indefinitely, because the cursor is still on the first position on your list, so hasNext() will always returns true.
Using next() the program looks like :
while (iteratorNames.hasNext()) {
String element = iteratorNames.next(); //now you can do what you want with this element
System.out.println(element);
}
Others have already mentioned how you use an Iterator--by querying it to see if it has a next value and then grabbing it via next() if it does.
However, you have the option of avoiding those low-level details altogether through a nice syntactic abstraction:
for (String name : listnames) {
System.out.println(name);
}
Give it a shot. In my opinion, it was one of the most helpful features of Java 5. Here is more information on it.
In your program System.out.println(iteratorNames); it will call toString() of Object class that will returns a string representation of the object (see implementation on toString())
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
That is why you are getting output like java.util.ArrayList$ListItr#a200d0c.
call next() It will returns the next element in the list. as follows:
System.out.println(iteratorNames.next());
use,
System.out.println((String)iteratorNames.next());
I've done most part of this. Anyone give me a small hint about how do I find the number of 10s in the list.
Eg. Input would be
[10,4,6,10,6,7]
Output must be
[4,6,6,7,0,0]
import java.util.ArrayList;
import java.util.List;
public class prob64 {
public static List output;
public static void getVal(List ll)
{
int count=0;
List ll1=new ArrayList();
for(int i=0;i<ll.size();i++)
{
if((int)ll.get(i)!=10)
{
ll1.add(ll.get(i));
}
if((int)ll.get(i)==10)
{
count++;
}
}
if(count>0)
{
ll1.add(8);
}
output=ll1;
System.out.println(output);
}
public static void main(String[] args) {
List<Integer> ll=new ArrayList();
ll.add(10);
ll.add(1);
ll.add(10);
ll.add(2);
prob64.getVal(ll);
}
}
The current output I'm getting is [1,2,0]. I'm supposed to get [1,2,0,0]
List.remove(Object) removes the first matching element. It also returns a boolean indicating if a removal was really done, so this should work :
while(ll.remove(10)) {
ll.add(0);
}
That is, as long as you find 10s to remove, add 0s. Note that List.add adds the element at the end of the list, which is your requirement (if I'm correct).
I suppose this is some kind of learning exercise, but I would advise you to find better names for your variable (ll & ll1 does not make your function easy to read).
You are adding only one zero at the end of the loop (in case 10s were found). You should count the number of 10s then add zeros as much as this number. Your program should look something like this:
int count=0;
List ll1=new ArrayList();
for(int i=0;i<ll.size();i++)
{
if((int)ll.get(i)!=10)
ll1.add(ll.get(i));
else
count++;
}
for(int j=0; j<count;j++)
ll1.add(0);
If count is number of 10's to add, use:
for(int j=0; j<count;j++){
ll1.add(8); // or ll1.add(0); ???
}
Few points to add to what others have mentioned above
I don't see any reason why you must define the output List to be static. When you define something(variables/functions) as static they are owned by the class rather that the objects and also it is a good programming practice not to change them using instance functions.What I mean is if you wish only to print there is no need of that output instance variable. You can directly print ll1.
Please use Generics in your code. When you know all you have in your list are integers specify it - Even in the function getVal(). I don't know how your code is compiling but you cannot cast Object to an int.
(int)ll.get(i)!=10
This code will fail. Try using Integer instead of int.
Your problem statement read replacing all 10's with 0's. So why are you adding 8 instead.It must be
ll1.add(0);
As other have specifies you need to add 0 as many time as your count is. So another loop is needed. Rest all look good.