Java: recursively map iteration

We have an object that looks like a "recursive" data structure.

Suppose we have a Person object whose structure is similar to this

public class Person {
    private String id;

    private Map<String,Person> persons;

    public Person(String id, Map<String,Person> persons){
        this.id = id;
        this.persons = persons;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Map<String, Person> getPersons() {
        return persons;
    }

    public void setPersons(Map<String, Person> persons) {
        this.persons = persons;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", persons=" + persons + "]";
    }

}

An approximate representation of this object will be: (sample data)

  Person p1 = new Person("Jim", ImmutableMap.of("A001",new Person("Mike",ImmutableMap.of("D001",new Person("Jack",ImmutableMap.of("E001",new Person("Kim",null))))),
                                                         "Z001",new Person("Adam",ImmutableMap.of("Y001",new Person("Eve",ImmutableMap.of("X001",new Person("Dave",null)))))));

Note 1: ImmutableMapfrom the google guava collection

Note 2: Assume that the “key” for the Card in the Person object is the name of the person.

Given a person’s name, what is the most efficient way to go through an iteration and get an identifier. ?

For example, if the input is "Eve", the output should be "Y001"

+4
source share
3 answers

Guava, , , Person:

public FluentIterable<Map.Entry<String, Person>> tree() {
    if (persons == null)
        return FluentIterable.from(ImmutableList.of());
    return FluentIterable.from(persons.entrySet())
            .transformAndConcat(
                entry -> Iterables.concat(ImmutableList.of(entry), entry.getValue().tree()));
}

Java-8:

public FluentIterable<Map.Entry<String, Person>> tree() {
    if (persons == null)
        return FluentIterable.from(ImmutableList.of());
    return FluentIterable.from(persons.entrySet())
        .transformAndConcat(
            new Function<Entry<String, Person>, Iterable<Entry<String, Person>>>() {
            @Override
            public Iterable<Map.Entry<String, Person>> apply(
                    Map.Entry<String, Person> entry) {
                return Iterables.concat(ImmutableList.of(entry), entry.getValue().tree());
            }
        });
}

Iterable, for-loop:

String name = "Eve";
for(Map.Entry<String, Person> e : p1.tree()) {
    if(e.getValue().getId().equals(name)) {
        System.out.println(e.getKey());
        break;
    }
}

FluentIterable:

System.out.println(p1.tree()
                     .firstMatch(e -> e.getValue().getId().equals(name))
                     .get().getKey());
+2

Guava TreeTraverser:

Iterable<Person> allPersons = new TreeTraverser<Person>() {
  @Override public Iterable<Person> children(Person p) {
     return p.getPersons().values();
  }
}.preOrderTraversal(rootPerson);
for (Person p : allPersons) {
  if (p.getId().equals(id)) {
    return p;
  }
}
+2

- . , . (, ), .

, , . .

, , . , , : , , . , .

public String iterate(String name) {
        if (persons != null) {
            for (Entry<String, Person> entry : persons.entrySet()) {
                Person value = entry.getValue();
                if (value.getId().equals(name)) {
                    return entry.getKey(); //Since the key of each map is the ID when they return the key
                } else {
                    String ans = value.iterate(name);
                    if (ans != null) {
                        return ans;
                    }
                }
            }
        }
        return null;
    }

, .

, , , , - .

public String iterate(String name) {
        if (persons != null) {
            for (Entry<String, Person> entry : persons.entrySet()) {
                Person value = entry.getValue();
                if (value.getId().equals(name)) {
                    return entry.getKey(); //Since the key of each map is the ID when they return the key
                }
            }

            for (Entry<String, Person> entry : persons.entrySet()) {
                String ans = entry.getValue().iterate(name);
                if (ans != null) {
                    return ans;
                }
            }
        }
        return null;
    }

- , .

I assume you need a top solution, this is more standard. However, I do not think that there is a huge difference between them. For another version of this file, see this tree traversal question .

0
source

Source: https://habr.com/ru/post/1629287/


All Articles