开发者

Need to loop over an array/list/whatever and *return to caller* each element -but the loop only runs once, of course

开发者 https://www.devze.com 2023-01-16 22:49 出处:网络
I\'m obviously missing something here, as this sound basic enough but yet... I have a collection of objects . I need to use each one of them as parameter in constructor for a new object and return eac

I'm obviously missing something here, as this sound basic enough but yet...

I have a collection of objects . I need to use each one of them as parameter in constructor for a new object and return each new object to the calle开发者_如何转开发r method, one by one.

But -if I loop over the collection obviously the loop only runs once, and only returns the 1st object.

Edit : Returning the whole collection or some new collection will not work because :

The caller method [not mine to change] runs inside a start() method of a Runnable ThingProvider, which returns a single Thing whenever a request is submitted to it. So, returning List is not possible.

Thanks :)


public List<T> loop(Collection<? extends U> coll) {
    List<T> a = new ArrayList<T>();
    for (U u : coll){
         a.add(new T(u));
    }
    return a;
}


Return a custom Iterator. Assumming your new objects are of class MyObject and the constructor accepts an Object:

public Iterator<MyObject> myObjectsIterator(final Iterator<? extends Object> it) {
    return new Iterator<MyObject>() {
        public boolean hasNext() {
            return it.hasNext();
        }

        public MyObject next() {
            return new MyObject(it.next());
        }

        public void remove() {
            it.remove();
        }
    };
}

And you would call it like this:

...
Iterator<MyObject> myIt = myObjectsIterator(myListOfObjects.iterator());
// Now you can pass myIt around as a normal object. It will remember
// which one is the next Object with which to construct a MyObject
// and will generate it on the fly
...
while (myIt.hasNext()) { // is there any MyObject remaining?
    MyObject myObj = myIt.next(); // gets the next MyObject
    // do something with myObj
}
...


This is a poorly worded question and I think as others have noted, just returning a new list of the objects is fine. But if you really want to process them one at a time while you're looping through it, you can use the command pattern.

public interface Command {
    void execute(NewType object);
}

Now in your caller method, you can do the following:

public void doSomething() {
    processList(myList, new Command() {
        void execute(NewType object) {
            // Do whatever you want with this object
        }
    });
}

And, in the method that will actually go through the list:

public void processList(Iterable<OldType> values, Command command) {
    for(OldType v : values) {
        NewType newType = new NewType(v);
        command.execute(newType);
    }
}


In java you can return only once. So if you want to get some informations from your methods either you wrap them into a "Big" Object (here a List) or you give to the method the means to put informations in your parameters.

You could have something like this :

public static void main(String... args){
    List<Parameter> parameters = methodToGetParameters();
    List<Result> results = generateObjectsFromList(parameters);
    for(Result result : results){
        handleAResult(result);
    }
}

public List<Result> generateObjectsFromList(List<Parameter> parameters){
    List<Result> results = new ArrayList<Result>();

    for(Parameter parameter : parameters){
        results.add(new Result(parameter));
    }

    return results;
}

Or like this :

public static void main(String... args){
    List<Parameter> parameters = methodToGetParameters();
    List<Result> results = new ArrayList<Result>();
    generateObjectsFromList(parameters, results);
    for(Result result : results){
        handleAResult(result);
    }
}

public void generateObjectsFromList(List<Parameter> parameters, List<Result> results){        
    for(Parameter parameter : parameters){
        results.add(new Result(parameter));
    }        
}

A third way to do this would be to use fields, but it's not really good to have a lot of fields if they're not really used (or only by one method).


On the same topic :

  • Java Object Oriented Design Question: Returning multiple objects in java(Updated)
  • Using a java method to return multiple values?


Return a collection from the method and in the collection implement a custom iterator to transform the input collection to the new collection. The following code shows how to do it using the Google Guava library:

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;

public class Test {

    static class Person {
        public final String name;
        public Person(String name) {
            this.name = name;
        }
    }

    public static Collection<Person> peopleFromNames(Collection<String> names) {
        return Collections2.transform(names, new Function<String, Person>() {
            public Person apply(String name) {
                return new Person(name);
            }});
    }

    public static void main(String[] args) {
        List<String> names = Arrays.asList("Brian", "Albert", "Roger");
        for (Person person : peopleFromNames(names)) {
            System.out.println(person.name);
        }
    }

}


do you mean using of delegates something like below

public class Test {

    private static class Person{
        private final String name;

        Person(String name){
            this.name = name;
        }

        @Override
        public String toString() {
            return return name;
        }
    }

    private interface Printer {
        void print(Object object);
    }

    public static void main(String[] args) {
        final String[] names = {"one", "two", "three"};
        final ArrayList<Person> people = construct(names, new Printer() {

            @Override
            public void print(Object object) {
                System.out.println(object.toString());
            }
        });
    }

    private static ArrayList<Person> construct(String[] names, Printer printer) {
        ArrayList<Person> people = new ArrayList<Person>();
        for (String name : names) {
            printer.print(new Person(name));
        }
        return people;
    }

}


It's Possible.

Check these Project for Java-yield , yield4Java, infomancers

If you're using this just once in your entire code, You're better off choosing a method from the other answers.


Return a list of the new objects.

0

精彩评论

暂无评论...
验证码 换一张
取 消