This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Can describe to me why my Iterator does not work. JDeveloper says that I must create a method for Iterator, but I don't have a clue what the program means with that. Therefore I ask for your help. The Program looks like this:
TestOrder:
package hej;
import java.util.*;
public class TestOrder {
public static void main(String[] args) {
OrderRegister orderregister = new OrderRegister();
Order order1 = new Order("123","Kop");
Order order2 = new Order("456","Salj");
Order order3 = new Order("789","Kop");
orderregister.addOrder(order1);
orderregister.addOrder(order2);
orderregister.addOrder(order3);
System.out.println(orderregister.sokOrder("123").getKopsalj());
orderregister.raderaOrder("456");
Order tmpOrder = orderregister.sokOrder("456");
if (tmpOrder == null) {
System.out.println("Fungerar!");
}
else{
System.out.println("Why u lie?");
}
System.out.println(orderregister.sokOrder("123").getKopsalj());
orderregister.sokOrder("123").setKopsalj("Salj");
System.out.println(orderregister.sokOrder("123").getKopsalj());
Iterator<Order> i=orderregister.iterator();
while(i.hasNext()){
System.out.println(i.next());
}
}
}
Order:
package hej;
import java.util.Iterator;
public class Order {
private String ordernr;
private String kopsalj;
public Order(String newOrdernr, String newKopsalj) {
setOrdernr(newOrdernr);
setKopsalj(newKopsalj);
}
public void setOrdernr(String ordernr) {
this.ordernr = ordernr;
}
public String getOrdernr() {
return ordernr;
}
public void setKopsalj(String kopsalj) {
this.kopsalj = kopsalj;
}
public String getKopsalj() {
return kopsalj;
}
public String toString()
{
return "Order: " + this.ordernr+", "+"Manover: "
+this.kopsalj;
}
}
OrderRegister:
package hej;
import java.util.ArrayList;
import java.util.Iterator;
public class OrderRegister {
private ArrayList<Order> orderArrayList;
public OrderRegister() {
orderArrayList = new ArrayList<Order>();
}
// Lagg till Order
public void addOrder(Order newOrder) {
orderArrayList.add(newOrder);
}
// Sok Order
public Order sokOrder(String ordernrSok) {
Order tmpOrder = null;
int i = 0;
boolean found = false;
while (i < orderArrayList.size() && !found) {
tmpOrder = orderArrayList.get(i);
if (tmpOrder.getOrdernr().equals(ordernrSok)) {
found = true;
}
i++;
}
if (!found) {
tmpOrder = null;
}
return tmpOrder;
}
// Ta bort Order
public void raderaOrder(String ordernrRadera) {
Order tmpOrder = null;
int i = 0;
boolean found = false;
while (i < orderArrayList.size() && !found) {
tmpOrder = orderArrayList.get(i);
if (tmpOrder.getOrdernr().equals(ordernrRadera)) {
orderArrayList.remove(i);
found = true;
}
i++;
}
}
// andra Orderuppgifter
public void setOrderUppgifter(String ordernr, String newKopsalj){
Order order = sokOrder(ordernr);
if (order != null) {
order.setKopsalj(newKopsalj);
}
}
}
You need to let the OrderRegister class implement Iterable.
T is the iterator data type, which is Order in your case.
So you get:
public class OrderRegister implements Iterable<Order>
The Iterable interface, requires you to define an iterator() method which returns an Iterator<E> object. In your case you do not require to create such an class, as you can grab the iterator object directly from your ArrayList:
public Iterator<Order> iterator() {
return orderArrayList.iterator();
}
Now you can use your class in this way:
for(Order order: orderregister) {
System.out.println(order.getKöpsälj());
}
Note: your while-loop will also still work
See http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Iterator.html.
For every iterator, you need to implement methods hasNext, next and remove.
Plus, your class orderregister doesn't have any method iterator(). You either need to inherit form a class that already has it implemented or you need to implement it by yourself.
let OrderRegister implements the Iterable interface and implement iterator than()
there you just can delegate to orderArrayList.iterator()
I assume your problem is this line:
Iterator<Order> i=orderregister.iterator();
because there is no method iterator() in your class OrderRegister.
Two solutions:
A) add the method iterator() (it could probably just do return orderArrayList.iterator();)
B) instead of wrapping an ArrayList, extend it!
public class OrderRegister extends ArrayList<Order> {
// No more orderArrayList!
}
Related
I have a problem with the following code:
Import java.util.ArrayList;
public class Car {
private String car;
private Car genCar = new Car();
ArrayList<String> allCars = new ArrayList<>();
public void setCar() {
genCar.setModel();
genCar.setCreator();
car = genCar.getModel() + "made by" + genCar.getCreator();
}
public void checkDouble() {
for (String search : allCars) {
while (search.equals(car)) {
setCar();
}
}
allCars.add(car);
}
public void repeater(){
for(int i = 0; i<52; i++){
setCar();
checkDouble();
}
}
}
Whenever I try to check for duplicates (which this code does) my program still puts the duplicate in the array when I actually try to avoid it this way.
Any solution so this works?
You do this:
public void checkDouble()
{
for (String search : allCars)
{
while (search.equals(car))
{
setCar();
}
}
allCars.add(car);
}
The problem with this is that, once you found a double, you generate a new car using setCar(), but you do not search the entire list again.
Do something like:
public void avoidDoubles()
{
while allCars.contains(car)
{
setCar(); // generate new, different car
}
allCars.add(car);
}
FWIW, you might want to change the name of some of the functions. I would call setCar() generateNewCar() or newCar().
I'm not sure what you're trying to do, but in checkDouble you are finding a duplicate and then adding it to the list.
If I understand you correctly, you don't need the loops, All you need to do is to use ArrayList.contains()
if(allCars.contains(someString))
{
System.err.println("Duplicate...");
} else
{
//setCar, addCar, etc.
}
My program is structured as follows: a class that represents an atomic concept which is essentially a String and another class that is made of a list of general concepts. Both classes extends the class Concept that is an abstract class, this means that in the list I could have both atomic concepts and intersection of concepts arbitrary nested.
Each concept, atomic or composed, is printed out by toString method.
Roughly speaking, this is based on this context-free grammar:
C : atom | (C and)+ C
Where C is the abstract class Concept, atom is AtomicConcept and (C and)+ C is Intersection.
This is the AtomicConcept class:
public class AtomicConcept extends Concept{
private String atomicConceptName;
public AtomicConcept(String c) {
this.atomicConceptName = c;
}
#Override
public String toString() {
return atomicConceptName;
}
}
This is che ConceptIntersection class:
import java.util.List;
public class ConceptIntersection extends Concept{
private List<Concept> list;
public ConceptIntersection(List<Concept> l) throws Exception {
if(l.size()>1)
{
this.list = l;
}
else
{
throw new Exception("Intersection needs at least two concepts!");
}
}
public String toString()
{
return Utils.conceptIntersection + Utils.lparen + Utils.splitConcepts(list) + Utils.rparen;
}
}
As you can see in toString function, I also created a method called splitConcepts that takes in input a list of general concepts and returns one string made of each concept separated by comma.
public static String splitConcepts(List<Concept> list)
{
String result = "";
for (Concept item : list) {
System.out.println(item);
result += item.toString() + comma;
}
result = result.substring(0, result.length() - 1);
return result;
}
Where is the problem?
I have trouble with this function because when I call a nested intersection in another one, this function never ends!
One example:
public static void main(String[] args) throws DLRException {
// TODO Auto-generated method stub
AtomicConcept atom = new AtomicConcept("one");
AtomicConcept at = new AtomicConcept("two");
List<Concept> list = new LinkedList<Concept>();
list.add(at);
list.add(atom);
DLRConceptIntersection intersection = new DLRConceptIntersection(list);
System.out.println(intersection); // works fine
list.add(intersection);
DLRConceptIntersection intersection2 = new DLRConceptIntersection(list);
System.out.println(intersection2); //loop never ends!
}
Is a correct approach to fix this problem?
You have a circular reference :
DLRConceptIntersection intersection = new DLRConceptIntersection(list);
list.add(intersection);
This causes the intersection's List to contain a reference to the same instance referred by intersection, which is why toString() run into infinite recursion.
I'm assuming you didn't intend intersection and intersection2 to share the same List.
You can avoid it if you create a copy of the List in the DLRConceptIntersection constructor:
public ConceptIntersection(List<Concept> l) throws Exception {
if(l.size()>1) {
this.list = new ArrayList<>(l);
} else {
throw new Exception("Intersection needs at least two concepts!");
}
}
I am having this issue where I have a PiorityBlockingQueue to sort the items in it. The are several options the user can sort the items being added into the queue.
The one I'm stuck at is trying to order the queue by the most occurences of an Item.
The choice of the comparison is determined in the constructor of MyQueue. But the counts of (eg. Low, Medium, High) isnt determined until later. When it is determined, I wanted to call the update(String lst) method from ItemComparator to update the hashmap so that the sorting is correct.
So my issue is I can't call that method. I know I'm missing something but I can't figure it out. Any help? Maybe there a better design than what I doing now?
public class ItemComparator implements Comparator<Item>
{
public void update(String lst){
test = lst;
}
public int compare(Item o1, Item o2) {
HashMap<String,Integer> priority = new HashMap<>();
priority.put("LOW", 1);
priority.put("MEDIUM", 2);
priority.put("HIGH", 3);
if (priority.get(o1.getPriority()) > priority.get(o2.getPriority())) {
return -1;
}
if (priority.get(o1.getPriority()) < priority.get(o2.getPriority())) {
return 1;
}
return 0;
}
}
This statement wont work from this class comparator.update(aString);
public class MyQueue implements AQueue{
private Comparator<Ticket> comparator;
private PriorityBlockingQueue<Ticket> listOfTickets;
private String policy;
BlockingQImpl(String processingPolicy) throws InvalidDataException {
setPolicy(processingPolicy.toUpperCase());
setComparator(policy);
}
private void setComparator(String policy) throws InvalidDataException {
if (policy.equals("THIS")) {
comparator = new ItemComparator(countString);
}
listOfTickets = new PriorityBlockingQueue<>(10, comparator);
}
public void addList(int id) {
ticks.add(id)
comparator.update(aString);
}
}
I think your problem is the compilation error at comparator.update(aString); right?
It is because you have declared comparator as Comparator<Ticket>, that means, you are "seeing" it as a Comparator, and in a Comparator, there is no update() method.
You should declare it as ItemComparator
i.e.
private ItemComparator comparator;
This question already has answers here:
How do I make 2 comparable methods in only one class?
(3 answers)
Closed 8 years ago.
I have some code to sort paths by date modified. I want to also write some code to sort the paths in reverse order, and might later want to add some other sorting methods. Is there any way to do all the sorting from a single class file? Or do I have to create another class PathSortByDateReverse, PathSortByCreated, PathSortByFoo, etc. Also, how would I use the different sorting methods?
import java.nio.file.Path;
import java.util.Comparator;
public class PathSortByDate implements Comparator<Path> {
#Override
public int compare(Path first, Path second) {
long seconddate = second.toFile().lastModified(); // get just the filename
long firstdate = first.toFile().lastModified();
if (firstdate == seconddate) {
return 0;
} else if (firstdate > seconddate) {
return 1;
} else {
return -1;
}
}
}
I then call it from the other class with:
public static ArrayList<Path> sortArrayListByDate(ArrayList<Path> pathlist) {
Collections.sort(pathlist,new PathSortByDate());
return pathlist;
}
Why not go for an anonymous inner classes?
public static final Comparator<Person> ID_DESC
= new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return -1 * p1.getId().comparedTo(p2.getId());
// reversed order
}
};
I would usually do it like this. Notice, the constructor is "private" and there is a "public factory method" to get an instance. There will ever exist two PathComparator instances at any given point. This is a big deal if you are into optimizing your code and using best practices.
import java.nio.file.Path;
import java.util.Comparator;
final public class PathComparator implements Comparator<Path> {
// comparator for in order
final private static PathComparator ascendingOrderComparatorDate = new PathComparator(true);
// comparator for reverse order
final private static PathComparator descendingOrderComparatorDate = new PathComparator(false);
final private int isAscendingOrderInt;
final public PathComparator getPathComparator(boolean isAscendingOrder) {
return isAscendingOrder ? ascendingOrderComparatorDate : descendingOrderComparatorDate;
}
private PathComparator(boolean isAscendingOrder) {
this.isAscendingOrderInt = isAscendingOrder ? 1 : -1;
}
#Override
public int compare(Path first, Path second) {
// for optimization (not required but highly recommended)
if(first == second) return 0;
long seconddate = second.toFile().lastModified(); // get just the filename
long firstdate = first.toFile().lastModified();
if (firstdate == seconddate) {
return 0;
} else if (firstdate > seconddate) {
return isAscendingOrderInt * 1;
} else {
return isAscendingOrderInt * -1;
}
}}
you dont need to make the reverse comparator, just make it and reverse it with
Collections.reverseOrder()
Is it possible to have multiple iterators in a single collection and have each keep track independently? This is assuming no deletes or inserts after the iterators were assigned.
Yes.
Sometimes it's really annoying that answers have to be 30 characters.
Yes, it is possible. That's one reason they are iterators, and not simply methods of the collection.
For example List iterators (defined in AbstractList) hold an int to the current index (for the iterator). If you create multiple iterators and call next() a different number of times, each of them will have its int cursor with a different value.
Yes and no. That depend of the implementation of the interface Iterable<T>.
Usually it should return new instance of a class that implement Iterable interface, the class AbstractList implements this like that:
public Iterator<E> iterator() {
return new Itr(); //Where Itr is an internal private class that implement Itrable<T>
}
If you are using standard Java classes You may expect that this is done this way.
Otherwise You can do a simple test by calling iterator() form the object and then run over first and after that second one, if they are depend the second should not produce any result. But this is very unlikely possible.
You could do something like this:
import java.util.ArrayList;
import java.util.Iterator;
public class Miterate {
abstract class IteratorCaster<E> implements Iterable<E>, Iterator<E> {
int mIteratorIndex = 0;
public boolean hasNext() {
return mStorage.size() > mIteratorIndex;
}
public void remove() {
}
public Iterator<E> iterator() {
return this;
}
}
class FloatCast extends IteratorCaster<Float> {
public Float next() {
Float tFloat = Float.parseFloat((String)mStorage.get(mIteratorIndex));
mIteratorIndex ++;
return tFloat;
}
}
class StringCast extends IteratorCaster<String> {
public String next() {
String tString = (String)mStorage.get(mIteratorIndex);
mIteratorIndex ++;
return tString;
}
}
class IntegerCast extends IteratorCaster<Integer> {
public Integer next() {
Integer tInteger = Integer.parseInt((String)mStorage.get(mIteratorIndex));
mIteratorIndex ++;
return tInteger;
}
}
ArrayList<Object> mStorage;
StringCast mSC;
IntegerCast mIC;
FloatCast mFC;
Miterate() {
mStorage = new ArrayList<Object>();
mSC = new StringCast();
mIC = new IntegerCast();
mFC = new FloatCast();
mStorage.add(new String("1"));
mStorage.add(new String("2"));
mStorage.add(new String("3"));
}
Iterable<String> getStringIterator() {
return mSC;
}
Iterable<Integer> getIntegerIterator() {
return mIC;
}
Iterable<Float> getFloatIterator() {
return mFC;
}
public static void main(String[] args) {
Miterate tMiterate = new Miterate();
for (String tString : tMiterate.getStringIterator()) {
System.out.println(tString);
}
for (Integer tInteger : tMiterate.getIntegerIterator()) {
System.out.println(tInteger);
}
for (Float tFloat : tMiterate.getFloatIterator()) {
System.out.println(tFloat);
}
}
}
With the concurrent collections you can have multiple iterators in different threads even if there inserts and deletes.