I encountered this error while using the haseNext() method for ArrayLists:
error: cannot find symbol
while(isduplicate == false && birthdays.hasNext())
this is my code:
import java.util.*;
class hello
{
public static void main(String args[])
{
Integer size = 4;
Integer count = 5;
Integer doubleinarray = 0;
for(Integer i = 0 ; i < count ; i++) {
List<Integer> birthdays = new ArrayList<Integer>();
birthdays = CreateSimulator(size);
Integer countdown = size;
boolean isduplicate = false;
while(isduplicate == false && birthdays.hasNext()) {
Integer date = birthdays.get(0);
birthdays.remove(0);
if(birthdays.contains(date)) {
isduplicate = true;
doubleinarray ++;
}
}
}
System.out.println(doubleinarray / count * 100);
}
public static List<Integer> CreateSimulator(int size)
{
List<Integer> Birthdays = new ArrayList<Integer>(size);
Random rand = new Random();
for(Integer i =0 ; i < size ; i++) {
Birthdays.add(rand.nextInt(364) + 1);
}
return Birthdays;
}
}
I didn't understand why it doesn't accept the hasNext. besides this, the rest of the code works fine.
appreciate your help
thanks :)
you have to do something like:
Iterator<Integer> birthdaysIterator = birthdays.iterator();
And with the birthDaysIterator you can call hasNext.
But this is not recommended nowadays.
You are better of performing a normal for, like:
with normal for:
for (int i = 0; i < birthdays.size(); i++) {
System.out.println(birthdays.get(i));
}
with for-each loop:
for (Integer birthday : birthdays) {
System.out.println(birthday);
}
with Java 8 streams:
birthdays.forEach((birthday) -> {
System.out.println(birthday);
});
EDIT:
Per #OHGODSPIDERS, if you use the other 3 versions that I suggested, you will run into ConcurrentModificationException. In order to avoid that, you can either stick with your iterator, or you can use an intermediate list to keep the elements which you want to delete, and remove them all afterwards.
Example:
List<String> toRemove = new ArrayList<>();
for (String birthday : birthdays) {
if (someCondition) {
toRemove.add(birthday);
}
}
birthdays.removeAll(toRemove);
birthdays is of type List which does not have a method of that name. What you are looking for is the iterator, which you can access like this:
Iterator<Integer> iterator = birthdays.iterator()
And use it to traverse the list. hasNext is a method of the type Iterator.
As mentioned, the List class does not have a hasNext() method
An alternate way to use this, would be to check if it is not empty
while (isduplicate == false && !birthdays.isEmpty()) {
Related
Learning about Arrays. I am not able to figure out why a new number is not added to the back of my existing array. I read in two textfiles in file_1.txt are the numbers '1 2 3' and in file_2.txt is the number '91'. Basically without the method of Void addBack() the program does what I expect, however by adding the method it seems not make a new Array. Even when I go over the elements[i] = elements[i-1] it won't print it as a whole. I am expecting to print for the first part
The numbers are: 1 2 3 and the second part The numbers are: 1 2 3 91.
public class ExampleLecture {
IntRow readIntRow(Scanner input) {
IntRow result = new IntRow();
while (input.hasNext()) {
result.add(input.nextInt());
}
return result;
}
IntRow setBack(Scanner input) {
IntRow result = new IntRow();
while(input.hasNext()) {
result.addBack(input.nextInt());
System.out.println("here");
}
return result;
}
void print(IntRow row) {
for (int i = 0; i < row.numberOfElements; i++) {
System.out.printf("%d ", row.elements[i]);
}
System.out.printf("\n");
}
void start() {
Scanner in = UIAuxiliaryMethods.askUserForInput().getScanner();
Scanner in2 =UIAuxiliaryMethods.askUserForInput().getScanner();
IntRow row = readIntRow(in);
IntRow row2 = setBack(in2);
System.out.printf("the numbers are: ");
print (row);
System.out.printf("the new numbers are: ");
print (row2);
}
public static void main(String[] args) {
new ExampleLecture().start();
}
}
package examplelecture;
class IntRow {
static final int MAX_NUMBER_OF_ELEMENTS = 250;
int[] elements;
int numberOfElements;
IntRow() {
elements = new int[MAX_NUMBER_OF_ELEMENTS];
numberOfElements = 0;
}
void add(int number) {
elements[numberOfElements] = number;
numberOfElements += 1;
}
void addBack(int number) {
for (int i = numberOfElements; i>0; i--) {
elements[i] = elements[i-1];
elements[i] = number;
}
}
}
You have 2 successive assignments which write to the same position:
elements[i] = elements[i-1];
elements[i] = number;
The value is alway overwritten with number, so the first statement has no effect.
Also in your addBack method your for cycle:
for (int i = numberOfElements; i>0; i--) {
What happens if numberOfElements is 0?
You call it addBack but it looks like a better name for the method is addFirst. Usually index 0 is considered the front, not the back.
First off, both the readIntRow() and setBack() methods create new IntRow objects row and row2. If you want the result to be appended to the first IntRow object created i.e. to row , you should call:
IntRow row = readIntRow(in);
IntRow row2 = row.setBack(in2);
and setBack() needs to be modified to:
IntRow setBack(Scanner input) {
while(input.hasNext()) {
this.add(input.nextInt());
System.out.println("here");
}
return this;
}
Note that in setBack(), if you are trying to append numbers to the end of the IntRow object, you should call add() instead of addBack() as above. If you are trying to add to the front, you should call addBack() [and it might be better to call it addFront() instead].
Also, in the implementation of addBack(), if you are trying to add to the front of the IntRow object, the element[i] = number operation should take place only once, after the loop. Otherwise all the values in indices <= numberOfElements would be overwritten with number.
void addBack(int number) {
for (int i = numberOfElements; i>0; i--) {
elements[i] = elements[i-1];
}
elements[0] = number;
}
Admittedly it is not entirely clear what you are trying to accomplish. But you may have several problems. The first is as follows:
IntRow setBack(Scanner input) {
IntRow result = new IntRow();
while (input.hasNext()) {
result.addBack(input.nextInt());
System.out.println("here");
}
return result;
}
IntRow has nothing in it since it is new. So all you are doing is iterating over the new file which has just 91 in it. Remember, result has no items. So it won't even iterate once in addBack.
So just do the following:
Change your addBack method to just add the numbers. Why use a loop to cascade down the elements since you are doing this within the same instance of IntRow? Just add it on to the end using the numberofElements as the next index.
void addBack(int number) {
elements[numberOfElements++] = number;
}
If you want to copy the contents of one IntRow object to another you would need another method in the IntRow class. Something like:
public void copy(IntRow r) {
for (int i = 0; i < r.numerOfElements; i++) {
elements[i] = r.elements[i];
}
numerOfElements = r.numberOfElements;
}
And keeping with good design it might be better to return numberOfElements in a method such as public int size();
public class MyArrayList<T> implements MyList<T>{
int num; //number of things in the list
T[] vals; //to store the contents
#SuppressWarnings("unchecked")
public MyArrayList() {
num = 0;
vals = (T[]) new Object[3];
}
public T getUnique(){
T distinct = null;
int count = 0;
for (int i=0; i<vals.length; i++){
distinct = vals[i];
for (int j = 0; j<vals.length; j++){
if (vals[j] == vals[i]){
count++;
}
if (count == 1){
return distinct;
}
}
}
if (distinct == null){
throw new IllegalArgumentException();
}
return distinct;
}
I am trying to work on a get Unique Method. A method getUnique that takes no arguments and returns the first value in the list that appears only once. (For example, calling the method on the list [1,2,3,1,2,4] would return 3 since 1 and
2 both appear more than once.) If the list is empty or all its values appear more than once, the method throws a NoSuchElementException
I have added some FIXME's to your code:
public T getUnique(){
T distinct = null;
int count = 0; // FIXME: move this initialization inside the i loop
for (int i=0; i<vals.length; i++){
distinct = vals[i];
for (int j = 0; j<vals.length; j++){
if (vals[j] == vals[i]){ // FIXME: use .equals() not ==
count++;
}
if (count == 1){ // FIXME: move this check outside the j loop
return distinct;
}
}
}
if (distinct == null){ //FIXME: no check needed, just throw it
throw new IllegalArgumentException();
}
return distinct; //FIXME: no valid return can reach this point
}
Patrick Parker's advice will fix your code, but I wanted to provide a cleaner and faster solution to the problem of finding a unique element in a list. This algorithm runs in time O(n) instead of O(n^2).
public static <T> Optional<T> getUnique(List<T> ls) {
// Create a map whose keys are elements of the list and whose values are
// lists of their occurences. E.g. [1,2,3,1,2,4] becomes {1->[1, 1],
// 2->[2, 2], 3->[3], 4->[4]}. Then elements.get(x).size() tells us how
// many times x occured in ls.
Map<T, List<T>> elements = ls.stream()
.collect(Collectors.groupingBy(x -> x));
// Find the first element that occurs exactly one time in ls.
return ls.stream().filter(x -> elements.get(x).size() == 1)
.findFirst();
}
You might call it like this:
Integer[] vals = {1,2,3,1,2,4};
System.out.println(getUnique(Arrays.asList(vals))
.orElseThrow(NoSuchElementException::new));
This code uses Java 8 streams and Optional. Below is another implementation of the same algorithm that doesn't use Java 8 language features; if you've never encountered streams, you may find it more understandable.
private static <T> T getUnique(List<T> arr) {
Map<T, Integer> numOccurrences = new HashMap<>();
for (T item : arr) {
numOccurrences.put(item, 1 + numOccurrences.getOrDefault(item, 0));
}
for (T item : arr) {
if (numOccurrences.get(item) == 1) {
return item;
}
}
throw new NoSuchElementException();
}
I have a continuous running thread in my application, which consists of a HashSet to store all the symbols inside the application. As per the design at the time it was written, inside the thread's while true condition it will iterate the HashSet continuously, and update the database for all the symbols contained inside HashSet.
The maximum number of symbols that might be present inside the HashSet will be around 6000. I don't want to update the DB with all the 6000 symbols at once, but divide this HashSet into different subsets of 500 each (12 sets) and execute each subset individually and have a thread sleep after each subset for 15 minutes, so that I can reduce the pressure on the database.
This is my code (sample code snippet)
How can I partition a set into smaller subsets and process (I have seen the examples for partitioning ArrayList, TreeSet, but didn't find any example related to HashSet)
package com.ubsc.rewji.threads;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.PriorityBlockingQueue;
public class TaskerThread extends Thread {
private PriorityBlockingQueue<String> priorityBlocking = new PriorityBlockingQueue<String>();
String symbols[] = new String[] { "One", "Two", "Three", "Four" };
Set<String> allSymbolsSet = Collections
.synchronizedSet(new HashSet<String>(Arrays.asList(symbols)));
public void addsymbols(String commaDelimSymbolsList) {
if (commaDelimSymbolsList != null) {
String[] symAr = commaDelimSymbolsList.split(",");
for (int i = 0; i < symAr.length; i++) {
priorityBlocking.add(symAr[i]);
}
}
}
public void run() {
while (true) {
try {
while (priorityBlocking.peek() != null) {
String symbol = priorityBlocking.poll();
allSymbolsSet.add(symbol);
}
Iterator<String> ite = allSymbolsSet.iterator();
System.out.println("=======================");
while (ite.hasNext()) {
String symbol = ite.next();
if (symbol != null && symbol.trim().length() > 0) {
try {
updateDB(symbol);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void updateDB(String symbol) {
System.out.println("THE SYMBOL BEING UPDATED IS" + " " + symbol);
}
public static void main(String args[]) {
TaskerThread taskThread = new TaskerThread();
taskThread.start();
String commaDelimSymbolsList = "ONVO,HJI,HYU,SD,F,SDF,ASA,TRET,TRE,JHG,RWE,XCX,WQE,KLJK,XCZ";
taskThread.addsymbols(commaDelimSymbolsList);
}
}
With Guava:
for (List<String> partition : Iterables.partition(yourSet, 500)) {
// ... handle partition ...
}
Or Apache Commons:
for (List<String> partition : ListUtils.partition(yourList, 500)) {
// ... handle partition ...
}
Do something like
private static final int PARTITIONS_COUNT = 12;
List<Set<Type>> theSets = new ArrayList<Set<Type>>(PARTITIONS_COUNT);
for (int i = 0; i < PARTITIONS_COUNT; i++) {
theSets.add(new HashSet<Type>());
}
int index = 0;
for (Type object : originalSet) {
theSets.get(index++ % PARTITIONS_COUNT).add(object);
}
Now you have partitioned the originalSet into 12 other HashSets.
We can use the following approach to divide a Set.
We will get the output as
[a, b]
[c, d]
[e]`
private static List<Set<String>> partitionSet(Set<String> set, int partitionSize)
{
List<Set<String>> list = new ArrayList<>();
int setSize = set.size();
Iterator iterator = set.iterator();
while(iterator.hasNext())
{
Set newSet = new HashSet();
for(int j = 0; j < partitionSize && iterator.hasNext(); j++)
{
String s = (String)iterator.next();
newSet.add(s);
}
list.add(newSet);
}
return list;
}
public static void main(String[] args)
{
Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("e");
int size = 2;
List<Set<String>> list = partitionSet(set, 2);
for(int i = 0; i < list.size(); i++)
{
Set<String> s = list.get(i);
System.out.println(s);
}
}
If you are not worried much about space complexity, you can do like this in a clean way :
List<List<T>> partitionList = Lists.partition(new ArrayList<>(inputSet), PARTITION_SIZE);
List<Set<T>> partitionSet = partitionList.stream().map((Function<List<T>, HashSet>) HashSet::new).collect(Collectors.toList());
The Guava solution from #Andrey_chaschev seems the best, but in case it is not possible to use it, I believe the following would help
public static List<Set<String>> partition(Set<String> set, int chunk) {
if(set == null || set.isEmpty() || chunk < 1)
return new ArrayList<>();
List<Set<String>> partitionedList = new ArrayList<>();
double loopsize = Math.ceil((double) set.size() / (double) chunk);
for(int i =0; i < loopsize; i++) {
partitionedList.add(set.stream().skip((long)i * chunk).limit(chunk).collect(Collectors.toSet()));
}
return partitionedList;
}
A very simple way for your actual problem would be to change your code as follows:
Iterator<String> ite = allSymbolsSet.iterator();
System.out.println("=======================");
int i = 500;
while ((--i > 0) && ite.hasNext()) {
A general method would be to use the iterator to take the elements out one by one in a simple loop:
int i = 500;
while ((--i > 0) && ite.hasNext()) {
sublist.add(ite.next());
ite.remove();
}
I have to make a custom iterator that iterators through an array endlessly. I have no clue how to do this considering I've never worked with iterators in java before. If anyone could help me out at all and explain to me, I'd appreciate it very much.
public class Numbers{
private int[] array;
public Numbers(int[] array){
this.array = array
}
public static void main(String[] args) {
Numbers n = new Numbers();
Iterator num = n.sequence();
for(int i = 0; i < 10; i++){
if (num.hasNext()){
System.out.print(num.next() + " ");
System.out.println();
}
}
}
}
See below:
public class Numbers implements Iterable<Integer> {
private int[] array;
private int i;
public Numbers(int[] array) {
this.array = array;
i = 0;
}
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
#Override
public boolean hasNext() { return true; }
#Override
public Integer next() {
int j = i;
i = (i + 1) % array.length;
return array[j];
}
#Override
public void remove() {}
};
}
}
You could then do:
Numbers n = new Numbers(new int[]{1,2,3});
for (int i : n)
System.out.println(i); // or anything else
This would result in the infinite loop:
1
2
3
1
2
3
1
2
...
Relevant javadocs:
- Iterator
- Iterable
Another way to do it is just to have an infinite while-loop as such:
int[] array = new int[]{1, 2, 3};
int i = 0;
while (true) {
System.out.println(array[i]); // or anything else
i = (i + 1) % array.length;
}
This is basically how an iterator works. This example uses a List, but you can use an iterator against any collection that implements java.lang.Iterable.
List<String> someList; // assume this has been instantiated and has values in it
ListIterator<String> it = someList.listIterator();
while (it.hasNext()) {
String value = it.next();
// do something with value
}
Pretty much, you instantiate the iterator by telling the collection to give you a reference to its iterator. Then you loop by calling hasNext(), which will keep you going until you have no more elements. The call to next() pulls the next item from the iterator and increments its position by one. A call to remove() will remove from the list the last item returned by next() (or previous().)
Note, of course, that I've been using java.util.ListIterator instead of java.util.Iterator because the ListIterator is a special implementation of Iterator optimized for use against lists, like in the example I gave above.
You cannot use an iterator against an array. You'd need to use a vanilla for-loop or convert it into a List or another object that implements Iterable.
To loop through the above list endlessly, your loop would look something like this:
while(it.hasNext()) {
String value = it.next();
// do processing
if (!it.hasNext()) {
it = someList.listIterator(); // reset the iterator
}
}
To loop through the array using a for-loop endlessly:
for (int i = 0; i < myArray.length; i++) {
myArray[i];
// do something
if (i == myArray.length - 1) {
i = 0; // reset the index
}
}
Alteratively you could have your Numbers class implement Iterable directly.
Work with iterators is basically always the same.
First get the iterator from your array:
Iterator iterator = yourArray.iterator();
Second iterate while it has items:
while(iterator.hasNext()) {
Object element = iterator.next();
}
Here is my code:
import java.util.*;
public class Multiply {
public static void main(String[] args) {
LinkedList<Integer>num = new LinkedList<Integer>();
num.add("1");
num.add("2");
num.add("3");
num.add("4");
num.add("5");
product( num );
}
public static void product(LinkedList<Integer> list) {
int index = 0;
Iterator<Integer>productw = list.iterator();
Integer next = productw.next()
while (productw.hasNext()) {
index++;
System.out.println("The product of the numbers is = " + num);
}
}
}
Initially have a multiplication identity ( i.e., 1 ) before your while loop. And keep multiplying to it the iterator values.
Psuedo - code :
public static void product(LinkedList<Integer> list)
{
Iterator<Integer>productw = list.iterator();
int result = 1;
for( int i=0; i<productw.size(); ++i ) {
result *= productw.get(i) ;
}
// result has the answer
}
Edit 1:
The above loop assumes that the list has at least 1 element. If list has no elements, then zero must be the answer which I assume you can easily program it.
You need to define an initial value for the product
And then change it in the loop
Also...Your loop will print the statement multiple times- you don't want that- right ?
HTH