Ok so the goal of the class is to override the two methods inside of the Enumeration object class. I believe my hasNextElement() method should work, any pointers on that would be appreciated. I, however, am having troubles with the nextElement() method. Excuse the improper commenting throught the class but the goal of nextElement() is to return one character at a time. I figured its just a simple loop but netBeans keeps giving me incompatible dataTypes, which makes sense because its a String method not a Char method. So I change it to char and I get
nextElement() in StringEnumeration cannot implement nextElement() in Enumeration return type char is not compatible with String where E is a type-variable:
Any help would be greatly appreciated. Do remember I am a beginner programmer so I may have done something wrong that is easily fixable.
public class StringEnumeration implements Enumeration<String> {
public String value;
public StringEnumeration(String initialValue) throws InvalidStringException {
if (initialValue == null || initialValue.length() == 0) {
throw new InvalidStringException("initialValue is either null or 0");
}
this.value = initialValue;
}
#Override
public boolean hasMoreElements() {
return value.length() != 0 || value != null;
}
#Override
public String nextElement() {
StringBuffer test = new StringBuffer(value);
for (int i = 0; i < value.length(); i++) {
return test.charAt(i);
}
}
}
The easiest is to keep the index you're at as a variable in the enumeration:
// we return characters
public class StringEnumeration implements Enumeration<Character> {
// the value
private String value;
// current index
private int idx=0;
public StringEnumeration(String initialValue) throws IllegalArgumentException {
if (initialValue == null || initialValue.length() == 0) {
throw new IllegalArgumentException("initialValue is either null or 0");
}
this.value = initialValue;
}
#Override
public boolean hasMoreElements() {
// can we still read
return idx<value.length();
}
#Override
public Character nextElement() {
// get current char and increment index
return value.charAt(idx++);
}
}
Your implementation has several problems.
First, in Enumeration<E> the E is not the type the enumeration is working on. It's the type that the nextElement() method is supposed to return. So an Enumeration<String> has a nextElement() method that returns String. But your implementation returns the result of charAt() - a method that returns the primitive char, not a String! You either have to return some sort of string (maybe a single-char string like "m") or a Character (because you can't make E a primitive type like char).
The next problem is that your hasNextElement() method is not actually correct. An Enumeration is intended to give you one element (character, in your case) of the data at a time, and each time you call nextElement() it moves ahead towards the end of the data. so hasNextElement() has to return true based on whether or not there is still another element to go through. Your implementation, however, will always return true for the same string. It will not give an indication when to stop calling nextElement().
Last, your nextElement() somehow thinks that it's going to return all the elements at the same time. This cannot work. An Enumeration can only give one element each time you call nextElement(). So using a loop inside it makes no sense. The proper way to do this is to keep state inside the Enumeration object, say a variable named next, that indicates where the next element is. Each time the caller calls nextElement(), you take that element, advance next, and return the element. One element at a time, no loops. The actual loop will be created by whoever is using the Enumeration, not by the Enumeration itself.
It is also this next field (or whatever you want to call it) that can help you to create a proper hasMoreElements() method. If the next reaches beyond the end of the string, hasMoreElements() has to return false, and nextElement() has to throw NoSuchElementException.
I think what you intend to implement is an Iterator<T> over the characters of a given string:
public class StringEnumeration implements Iterator<Character> {
private final String value;
private int index = 0;
public StringEnumeration(String initialValue) {
if(initialValue == null) {
this.value = "";
} else {
this.value = initialValue;
}
}
#Override
public boolean hasNext() {
return index < value.length();
}
#Override
public Character next() {
try {
return test.charAt(this.index);
} finally {
this.index++;
}
}
#Override
public void remove() {
//can be done. Necessary?
}
}
(You can use an Enumeration<T> by simply replacing Iterator<Character> with Enumeration<Character>; and hasNext and next with hasMoreElements and nextElement and remove the remove method.
This iterator considers that the null String and the empty string "" contain both zero characters.
An iterator needs to store a state in the iteration process: the index of the character to enumerate. Initially the index is set to 0. After each item, the index is incremented.
Furthermore the test is simply whether the value has already reached the end of the String.
The main problem with your code is the following:
#Override
public String nextElement() {
StringBuffer test = new StringBuffer(value);
for (int i = 0; i < value.length(); i++) {
return test.charAt(i);
}
}
You use a for-loop but with a return statement. If you thus ask for the nextElement Java will start iterating and immediately return the first character. Furthermore this probably won't compile since the Java compiler can't figureout test has at least one element and thus it is possible that the for loop is never executed.
Other advice
Please always make fields private. By making fields public, a class can no longer guarantee the consistency of its state.
Furthermore Iterator is a modern version of Enumeration (although there is some discussion about this).
//know acess modifiers well...
private String value;
private Integer currentPosition;
public StringEnumeration(String initialValue) throws InvalidStringException {
if (initialValue == null || initialValue.length() == 0) {
throw new InvalidStringException("initialValue is either null or 0");
}
this.value = initialValue;
}
//you would return false when the list is empty OR the current position is
//past the end of the string
#Override
public boolean hasMoreElements() {
return value.length() != 0 || currentPosition < value.length();
}
//you would return the character at the current position
#Override
public char nextElement() {
return value.charAt(currentPosition++);
}
Related
I need to write a code to returns true if the first argument contains a number greater than the second argument; returns false otherwise. Given that a list of integers(first argument) is compared to an integer(second argument). I must use Iterator to implement this function.
This is the code I have so far:
public class ListHasGreater {
public static boolean hasGreater(List<Integer> numbers, int number) {
// write your code here
Iterator<Integer> selectedNum = numbers.iterator();
if (selectedNum.hasNext()){
int result = selectedNum.next();
while (result > number){
return true;
}
return false;
}
}
}
And I got this error error: class, interface, or enum expected
I'm not sure if my code is logically correct and don't know how to solve this error.
You are returning from a conditional, you should also add a return statement at the end of loop.
Instead of
while (result > number){return true;} it should be if(result > number) return true
The explicit use of iterators is quite an old way of programing, instead you can use a foreach loop and let Java convert this into iterators at compilation.
public static boolean hasGreater(List<Integer> numbers, int number) {
for (int numInList : numbers) {
if (numInList > number) {
return true;
}
}
return false;
}
I need some help with 2 methods that I'm using.
My first method looks at each character after the first (0th) in the string s and checks if they're digits but I cannot get it to fully work.
/**
* Forms the latter 5 characters of the accountNum String into a substring
which is checked to
* see if all characters are positive integers
*/
public Boolean hasValidDigits(String s)
{
for(int i=1; i<s.length(); i++)
if (Character.isDigit(s.charAt(i))) {
return true;
}
}
The issue with the method is it's asking for a return statement for the 'for' and I'm not sure why.
My second method calls methods from other parts of the class to check a string s.
/**
* Checks the following three criteria:
* - Is a string of length 6
* - Starts with a capital Letter
* - Subsequent characters are positive integers
*/
public Boolean isValidAccountNum(String s)
{
if (s.isValidLength() s.isValidStart() s.hasValidDigits()) {
return true;
} else {
return false;
}
}
The issue with this method is it's saying "Cannot find symbol - method isValidLength()
I'm guessing it would have same error with the other methods.
The methods I want to call are all made public. I'll include the isValidLength() below.
/**
* Checks if the variable accountNum has a length of 6 characters
*/
public Boolean isValidLength(String s)
{
if (s.length()==6) {
return true;
} else {
return false;
}
}
Your first method might not return anything if your if condition is not true so you need to return something at last line of function.
Your second method does not have passed any parameters and syntactically incorrect as well.
Please check out your language syntax first and practice some basic examples for your understanding of java
Your methods accept a String as a parameter, they are not part of the String class. So you have to do this isValidLength(s) rather than s.isValidLength().
Further, you cant have multiple method calls inside the parenthesis of an if statement, without a logical operator in between (&& for and, || for or).
Also, your hasValidDigits does not do what you think, it will return true if one of the character is a digit, rather than all of them. Also, the first part of the javadoc comment on this method is nowhere near true. It also lacks a return when the if statement never evaluates to true.
So what you want is something like this:
public Boolean isValidLength(String s) {
return s.length == 6;
}
//this checks all characters of the string though,
//your javadoc said something about checking the last 5 characters..
public Boolean hasValidDigits(String s) {
for(int i=1; i<s.length(); i++)
if (!Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
public Boolean isValidAccountNum(String s) {
return isValidLength(s) && isValidStart(s) && hasValidDigits(s);
}
The first method might performs a loop but will return at the first iteration if it is a digit it does not check the whole string and there is no false returned e.g.:
public Boolean hasValidDigits(String s) {
for (int i = 1; i < s.length(); i++) {
if (!Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
the isValidAccountNum method can just return the statement as it is already a boolean expression
return s.isValidLength() && s.isValidStart() && s.hasValidDigits();
same for the isValidLength method for the same reason:
return s.length()==6;
I am getting a warning that watchStore.contains(s) is a suspicious call to java.util.Collection#contains. How can I fix it? I want to use contains() to find a particular object with the matching serial number.
public Watch findWatchBySerialNumber(long srch) {
long s = srch;
Watch watch = null;
for(int i = 0; i < watchStore.size(); i++) {
watch = watchStore.get(i);
if(watchStore.contains(s)) {
System.out.print("item found");
return watch;
}
}
System.out.print("item not found");
return null; // watch is not found.
}
Presuming that Watch is the class, watchStore is a List<Watch>, and that a field serialNo exists on Watch...
public Optional<Watch> findWatchBySerialNumber(long serial) {
return watchStore.stream()
.filter(w -> w.getSerialNo() == serial)
.findFirst();
}
If you're not using Java 8, the code is close, but a bit more dangerous since you have the chance to return null. If you can use Guava's Optional, that'd be a better choice here.
public Watch findWatchBySerialNumber(long serial) {
for(Watch w : watchStore) {
if(w.getSerialNo() == serial) {
return w;
}
}
return null;
}
Your contains isn't going to work since your list doesn't contain Longs, it contains Watchs. This is also why the compiler sees it as dubious; contains accepts an Object but it will return false if what you're looking for doesn't have a comparable equals for what's in your list.
You have to iterate over the entirety of your collection to find it in this scenario, especially since you're looking for a specific property on those objects as opposed to a specific, easy-to-provide value.
please how can I fix that. I want to use the contain() to find a
particular object with the matching serial number.
In that case override Watch's equals() to use serialNumber field for comparison.
Then add constructor that accepts serialNumber.
public class Watch {
private final long serialNumber;
public Watch(long serialNumber) {
this.serialNumber = serialNumber;
}
#Override
public boolean equals(Object obj) {
return obj == this ||
(obj instanceof Watch && ((Watch)obj).serialNumber == serialNumber);
}
#Override
public int hashCode() {
return (int)serialNumber;
}
}
Replace if(watchStore.contains(s)){ with if(watchStore.contains(watchToFind)){ where Watch watchToFind = new Watch(s);
you can use contains method from org.apache.commons.lang.ArrayUtils package.
Checks if the value is in the given array.
The method returns false if a null array is passed in.
Parameters:
array the array to search through
valueToFind the value to find
Returns:
true if the array contains the object
long [] imageHashes= {12l,13l,14l,15l};
System.out.println(ArrayUtils.contains(imageHashes, 13l));
The method is not returning the value of the local variable.
Can I use the value of local variable index from the following method
public boolean contains(Object input) {
int index = 0;
while(myAsetIterator.hasNext()) {
index++;
if(input.equals(myAsetIterator.next())) {
return true;
}
}
return false;
}
in this method as the index of the array of the object that I want to remove.
public boolean remove(Object o) {
int count = 0;
if(o == null) {
return false;
}
if(contains(o)) {
genArray[index] == null;
}
if (count > 0) {
System.out.println(count+" same elements were present in Aset. "
+ "Removed all those "+count+" elements from Aset.");
return true;
}
return false;
}
I know the scope of a local variable is limited to the method it's declared in. But there might be a way that I might not now yet to make this happen without using a field/instance variable.
No. The whole point of it being local to a method is that it only exists within that method. The options are:
Use an instance field, i.e. make it part of the state of the object. That's unlikely to be appropriate.
Use a static field, i.e. make it part of the static of the type. That's almost certainly inappropriate.
Change the existing method to return the information you want.
Create a new method to return the information you want.
Duplicate the existing code within remove so that you can get the index. That would be sad :(
As an example of the last two, you could write:
public int indexOf(Object input) {
int index = 0;
while(myAsetIterator.hasNext()) {
index++;
if (input.equals(myAsetIterator.next())) {
return index;
}
}
return -1;
}
public boolean contains(Object input) {
return indexOf(input) == -1;
}
... then in your remove method, you'd use indexOf instead of contains.
My problem is this: I have an iterator class which is supposed to iterate through elements in a given data structure, <E> let's say, but what I have managed to accomplish is that when I pass in the data structure it will iterate the data structure itself.
ie. DynamicIterator it = new DynamicIterator(da);
say da is an array the output will be [1,2,3,4,5,6] instead of 1,2,3,4,5,6
My issue is, more than anything, understanding the generally accepted practice for dealing with this more than the issue itself.
edit for code:
public class X<E>
{
private final E[] rray;
private int currentIndex = 0;
public X(E... a)
{
//if the incoming array is null, don't start
if(a == null)
{
System.out.println("Array is null");
System.exit(1);
}
//set the temp array (rray) to the incoming array (a)
this.rray = a;
}
//hasNext element?
public boolean hasNext()
{
return rray.length > currentIndex;
}
//next element (depends on hasNext())
public E next()
{
if (!hasNext())
{
System.out.println("Element doesn't exist, done");
System.exit(1);
}
return rray[currentIndex++];
}
//return array
public E[] access()
{
return rray;
}
}
You won't be able to do this with a completely generic parameter <E> - how would you iterate through a Throwable, for example? What your class X does at the moment is accept any number of objects in its constructor, and then simply returns each of those objects in turn.
If you restricted the bounds of the objects passed in to implement e.g. Iterable, then you can actually start to "look inside" them and return their contents:
public class X<E> {
private final Iterator<E> it;
public X(Iterable<E> a) {
it = a.iterator();
}
public boolean hasNext() {
return it.hasNext();
}
public E next() {
return it.next();
}
}
Although this doesn't really accomplish anything different to just using a.iterator() directly instead of an instance of X...