I have a LinkedBlockingQueue and I want to check if there is a certain order of elements in the queue without removing the elements. I was hoping there was method I could use to peek at a particular spot in the queue. For example, queue.peekSpot(0) would return the head and quque.peekSpot(queue.size()) would return the tail. Right now I have this method but it removes the things it is reading. The queue is a type char by the way.
public boolean checkString(String string) {
if (string.length() < 1) {
return true;
}
char input = queue.take();
if (input == string.charAt(0)) {
return checkString(string.substring(1));
}
return false;
}
If I could use a peekSpot() method, this could be done as follows, greatly simplifying the code.
public boolean checkString(String string){
for(int i = 0; i < string.length(); i++){
if(!(string.charAt(i) == queue.peekSpot(i))){
return false;
}
}
return true;
}
Somebody might say, what if that spot doesn't exist? Well then it might wait for that spot to exist. I am using a queue instead of an ordinary string because this is a serial feed and the string would have to constantly change. Any ideas?
There is no direct way to i.e access items by index. but You can call toArray(), which would return you an array and then you can access index locations. Something like this.
String peekSpot(Queue<String> queue, Integer index){
if(queue == null){
throw new IllegalArgumentException();
}
Object[] array = queue.toArray();
return (String)array[index];
}
Related
I'm trying to do a linkedlist for an assigment i have, this ask explicitly to create, from scratch a linkedlist and some derivated types like a queue and a stack, this is just some college homework, and i realize how to make a node class and a linkedlist class, but i'm struggling to create the addAll() method in this linkedlist class, this is what i have.
if i must bet, i say is the Collection c one, but then, i'm trying to add list of stuff there, in order to pass him's content to the new list, obiusly is not ready and obiusly doesn't work.
Can you tell me how i can pass some kind of "proto-list" in order to pass them data inside the new list?
(I know i must use somekind of for(objects) but i'm failing to pass some data through the parameter, which will be the right parameter to put there?)
public boolean addAll(Collection c) {
for (int i = 0; i < (this.listaNodos.size()); i++) {
//for (T someT : c){
// Node newNodo = new Node(someT);
//}
//i know the one down there is not gonna do anything, because
//i'm not accesing the data, but one problem at a time would ya ;)
Node newNodo = new Node(someT);
Node actualNodo = this;
boolean processFinished = false;
try{
if(index >= this.listaNodos.size() || index < 0){
throw new IndexOutOfBoundsException();
}
do{
if(index == actualNodo.getIndex())
{
actualNodo.setData(someT);
processFinished = true;
return true;
}
else
{
actualNodo = actualNodo.nextNode;
}
}while(!processFinished);
return false;
}catch(IndexOutOfBoundsException ex)
{
throw ex;
}
}
return false;
}
Can you tell me how to fix it to make it work?
Any request for clarification, constructive comment, or question would be greatly apreciated too.
Thanks in advance
I assume you already have an add() method of some sort right? If so, you can go over each element in c and add it using the add method:
public boolean addAll(Collection<T> c) {
boolean changed = false;
for (T t:c) {
changed |= this.add(t);
}
return changed;
}
I'm assuming the returned boolean means whether this list has changed, this is how it is defined in the Collection contract: https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#addAll(java.util.Collection).
You were also missing a generic type for your add method, so I added one. I assume your class definition looks somthing like this?
public class MyLinkedList<T>
I'm trying to create a recall program that sends text messages to 200+ people and then searches an email that the replies are forwarded too.
This method is supposed to search the array list of replies that is built using another method, but it doesn't work correctly. It will only work if the very first message on the array list matches the very first number in the contact list.
Those are some other problems, but my main question here is why does it say that the code specifically inside of my for loop is dead code?
public static boolean searchForPhone(String phone){
CharSequence phoneN = phone;
for(int i=0;i<myMessages.size();i++){
if(myMessages.get(i).contains(phone)){
return true;
}
else{
return false;
}
}
return false;
}
This is your code, properly formatted:
public static boolean searchForPhone(String phone) {
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
} else {
return false;
}
}
return false;
}
The construct flagged as Dead code is the i++ in the for-loop header. It is indeed dead code because the for loop's body unconditionally makes the method return. Therefore the "step" part of the for header is unreachable aka. dead.
The same fact makes your code perform incorrectly, BTW. Removing the else clause would be a big improvement.
Will this help?
public static boolean searchForPhone(String phone){
CharSequence phoneN = phone;
for(int i=0;i<myMessages.size();i++){
if(myMessages.get(i).contains(phone)){
return true;
}
}
return false;
}
Look you are looping over n-element list. When you get first element on the list you got if/else statement.
So you will HAVE TO either of 2 things, both of witch is return. So your program will exit on first element returned.
To make it simplier, your code is equal to:
CharSequence phoneN = phone;
if (myMessages.size() ==0 ){
return false;
}
return myMessages.get(0).contains(phone);
Try from Window > Preferences > Java > Compiler > Error/Warnings
Change Dead code (e.g 'if(false)') and Unnecessary 'else' statement to Error.
Your loop always returns from the function at the end of the first iteration. This makes i++ dead code since it never executes.
Anyway, remove the else clause to fix the code.
In the else part you need to continue to search. Else if your fist element is not the matching one will return false and not going to check other element.
public static boolean searchForPhone(String phone) {
CharSequence phoneN = phone;
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
} else {
//return false this conditional return cause
// the complain it as dead code. Since for loop will become not
//loop
continue; // will search for other elements.
}
}
return false;
}
Now you can simplify this code to following because else part is not really necessary.
public static boolean searchForPhone(String phone) {
CharSequence phoneN = phone;
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
}
}
return false;
}
I'm trying to use a method to compare t2o different lists. Basically I want to pass two different lists to a method which will return true or false if the elements of one array list are contained in the other using .contains. Right now it only returns true - and I'm not sure why. I'd like it to return false. If someone could help me figure this out, that would be great.
public class ArrayListTest {
public static void main(String[] args) {
List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<String>();
list1.add("cat");
list1.add("dog");
list1.add("zebra");
list1.add("lion");
list1.add("mouse");
//Test Values
//list2.add("cat");
list2.add("lizard");
boolean doesitcontain = contains(list1, list2);
System.out.println(doesitcontain);
}
public static boolean contains (List<String>list1, List<String>list2){
boolean yesitcontains;
for(int i = 0; i < list1.size(); i++){
if(list2.contains(list1.get(i))){
System.out.println("Duplicate: "+list1.get(i));
yesitcontains = true;
System.out.println(yesitcontains);
}else{
yesitcontains = false;
System.out.println(yesitcontains);
}
}
if (yesitcontains = true){
return true;
}else
return false;
}
}
You have inadvertently used the assignment operator where you intended the equality operator. In your specific case you should rewrite all this:
if (yesitcontains = true){
return true;
}else
return false;
}
to just
return yesitcontains;
and avoid any chance of confusion.
Furthermore, your algorithm will not work because you should return true immediately when you see a duplicate. Instead you go on with the loop and "forget" your finding. You can expect this to always return false except if the very last elements coincide.
In a wider context, I should also give you the following general advice:
Avoid indexed iteration over lists. Not all lists are ArrayLists and may show O(n) complexity for get(i). Instead use the enhanced for loop, which is safer, more concise, and more obvious;
Know the library: if you're just after confirming there are no duplicates, just Collections.disjoint(list1, list2) would give you what you need;
Be aware of algorithmic complexity: checking for duplicates in two lists is O(n2), but if you turn one of them into a HashSet, you'll get O(n).
Taking everything said above into account, the following would be an appropriate implementation:
static boolean disjoint(Collection<?> c1, Collection<?> c2) {
for(Object o : c1)
if (c2.contains(o))
return true;
return false;
}
If you look at Collections.disjoint, you'll find this exact same loop, preceded by a piece of code which optimizes the usage of sets for reasons described above.
Seems to me your method should be rewritten to:
public static boolean contains(List<String>list1, List<String>list2) {
return list2.containsAll(list1);
}
The code you currently have actually only checks if the last element of list1 is also in list2.
If you're actually looking for a contains any, this simple solution will do:
public static boolean contains(List<String>list1, List<String>list2) {
for (String str : list1) {
if (list2.contains(str)) {
return true;
}
}
return false;
}
if (yesitcontains = true){
should be
if (yesitcontains == true){
== is for comparison and = is for assignment.
if (yesitcontains = true){
will always evaluate to if(true) which causing return true;
EDIT:
(OR)
simply return yesitcontains; as commented.
if (yesitcontains == true) { } // use `==` here
or just
if (yesitcontains) { }
The below code assigns true to yesitcontains , and the expression will always be true.
if (yesitcontains = true) { }
There is no point of if() in your code , you can simple return yesitcontains;
EDIT: Solved. Returning a 0 works, apparently!
Ok so long story short, I have to return an int value, but nothing when a Linked List is empty. How do I do it?
public int countDuplicates() {
int duplicates = 0;
ListNode current = front;
int num = current.data;
current = current.next;
while(current != null) {
if(current.data == num) {
duplicates++;
} else {
num = current.data;
}
current = current.next;
}
return duplicates;
}
When I try this:
if(front == null) {
return ;
}
This doesn't work. What can I do?
You can rather throw an IllegalArgumentException: -
if(front == null) {
throw new IllegalArgumentException("List is empty");
}
If your method returns an int you must determine an acceptable value to represent "nothing". Such as 0 or if valid results are >= 0, use a negative value such as -1 to indicate "nothing".
Alternatively, modify your method to return an Integer object in which case you can return null.
It is possible for you to either define a fixed value, such as Integer.MIN_VALUE, that would indicate that the list is empty, or change the declaration of your method to public Integer countDuplicates(), and return null when the list is empty.
To keep the code as you have it now, you must either return an int, throw an exception, or exit.
Return an int: You'll have to specify a certain int value as the "fail" value and make sure that it is never the case that this value is hit during "normal" execution.
Throw an exception: Detailed in another answer - you've already shot it down.
Exit the program... if it makes sense to do that.
The best option may be to change the code - make the function return an Integer, for example, so the null option is there. There are surely other ways to work around it, as well.
you can change the return value from int to object like this
public Object countDuplicates() {
if(////condition)
return ///int;
else
return null;
You could return a negative value or change the return type to string and parse the result to int.
If you don't want to (or can't) throw an exception, return some "exceptional value", such as a negative number. For example, Java has a lot of indexOf(Object somethingToLookFor) methods that return a -1 if the item isn't found.
In your example, -1 works as exceptional because there can never be -1 duplicates.
Personally, I would just return 0 for an empty List. An empty list has 0 duplicates. But if the spec insists on something exceptional, return -1.
public boolean isEmpty(){
if (head == null) return true;
else return false ;
}
I want to navigate into a list by identifier.
1- I manage/create a list.
2- I create function to get next item of a identifier element from my list
Can you help me to fix this code?
Prepare the list
List<String> myList = new ArrayList<String>();
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("4");
myList.add("5");
public String function getNext(String uid) {
if (myList.indexOf(uid).hasNext()) {
return myList.indexOf(uid).nextElement();
}
return "";
}
public String function getPrevious(String uid) {
return myList.indexOf(uid).hasPrevious() ? myList.indexOf(uid).previousElement() : "";
}
You could use an index to lookup your String which is faster and simpler however to implement the functions as you have them.
public String getNext(String uid) {
int idx = myList.indexOf(uid);
if (idx < 0 || idx+1 == myList.size()) return "";
return myList.get(idx + 1);
}
public String getPrevious(String uid) {
int idx = myList.indexOf(uid);
if (idx <= 0) return "";
return myList.get(idx - 1);
}
Using a List.get(i) is O(1) which makes keeping the index the fastest option. List.indexOf(String) is O(n). Using a NavigatbleSet might appear attractive as it is O(log n), however the cost of creating an object is so high that the collection has to be fairly large before you would see a benefit. (In which case you would use the first option)
If your elements are not repeated, what you need is a NavigableSet:
http://download.oracle.com/javase/6/docs/api/java/util/NavigableSet.html
The methods higher and lower are what you are looking for.
Lists don't have a nextElement() method. indexOf returns the integer index of the item. You could simply add (or subtract) one to get the next (or previous) item:
public String function getNext(String uid) {
var index = myList.indexOf(uid);
if (index > -1) {
try {
return myList.get(i+1);
} catch ( IndexOutOfBoundsException e) {
// Ignore
}
}
return ""; // consider returning `null`. It's usually a better choice.
}
However looking up an object with indexOf on ArrayList is a very slow process, because it has to check every single entry. There are better ways to this, but that depends on what you are actually trying to achieve.