it-swarm.com.de

Die effizienteste Methode, um die Sammlung aller IDs in einer Sammlung von Entitäten zu finden

Ich habe eine Entität:

public class Entity
{
    private long id;    
    private String data;

    public long getId() {
        return id;
    }

    public String getData() {
        return data;
    }
}

und eine Sammlung von Entitäten:

Collection<Entity> entities= ...

Was ist der effizienteste Weg, um den Collection<Long> aller IDs in entities zu finden?

15
rapt

Vorausgesetzt, du hast

class Entity {
    final long id;
    final String data;

    public long getId() {
        return id;
    }

    public String getData() {
        return data;
    }

    Entity(long id, String data) {
        this.id = id;
        this.data = data;
    }
}

In Java 8 können Sie schreiben

Collection<Entity> entities = Arrays.asList(new Entity(1, "one"), 
                  new Entity(11, "eleven"), new Entity(100, "one hundred"));
// get a collection of all the ids.
List<Long> ids = entities.stream()
                         .map(Entity::getId).collect(Collectors.toList());

System.out.println(ids);

druckt

[1, 10, 100]

Wie Sie sich vorstellen können, ist dies in Java 7 oder weniger ziemlich hässlich. Beachten Sie, dass Entity.getId bei Anwendung auf map () bedeutet, dass diese Methode für jedes Element aufgerufen wird.

Der wirklich interessante Teil ist, dass Sie dies tun können.

List<Long> ids = entities.parallelStream()
                         .map(Entity::getId).collect(Collectors.toList());

In den meisten Fällen wird die Verwendung eines parallelen Streams die Leistung beeinträchtigen, macht es jedoch einfacher, es zu probieren und erstaunlich leicht zu sehen


Der effizienteste Weg ist das Erstellen oder Erstellen einer Karte.

Map<Long, Entity> entitiesMap = ...
// get all ids
Collection<Long> addIds = entitiesMap.keySet();

// look up entities by id.
List<Long> ids = ...
List<Entity> matching = new ArrayList<>();
for(Long id: ids)
    matching.add(entitiesMap.get(id));
33
Peter Lawrey

Sie werden nichts kürzer bekommen als:

Collection<Long> ids = new ArrayList<>();
for (Entity e : entities) ids.add(e.getId());

Ich gehe davon aus, dass alle Möglichkeiten die Sammlung durchlaufen würden

Nicht unbedingt. Dadurch wird eine Auflistung erstellt, die direkt von der zugrundeliegenden Entitätenauflistung unterstützt wird (zukünftige Änderungen an der Entitätsauflistung werden in der IDs-Auflistung angezeigt):

Collection<Long> ids = new AbstractCollection<Long>() {
    @Override
    public int size() {
        return entities.size();
    }

    @Override
    public Iterator<Long> iterator() {
        return new Iterator<Long>() {
            private Iterator<Entity> base = entities.iterator();
            @Override public boolean hasNext() { return base.hasNext(); }
            @Override public Long next() { return base.next().getId(); }
            @Override public void remove() { base.remove(); }
        };
    }
};
2
Boann

Ich weiß nicht, ob dies notwendigerweise das effizienteste ist, aber für Pre-Java 8 benutze ich gerne Eigenschaftsschnittstellen wie hier beschrieben: http://blog.cgdecker.com/2010/06/property -interfaces-and-guava.html

Wie im Blogbeitrag beschrieben, haben Sie eine einfache Schnittstelle mit der Bezeichnung HasId:

public interface HasId {
    long getId();
}

Ihre Entity-Klasse würde so aussehen:

public class Entity implements HasId {
    private long id;    
    private String data;

    public long getId() {
        return id;
    }

    public String getData() {
        return data;
    }
}

und Sie hätten irgendwo eine einfache Funktion wie diese:

public class ToId implements Function<HasId, Long> {
    public Long apply(HasId hasId) {
        return hasId.getId();
    }
}

Schließlich, um davon Gebrauch zu machen:

Collection<Long> ids = Collections2.transform(entities, new ToId());

Dies ist übertrieben, wenn Sie es nur für eine Sache benötigen, aber wenn Sie eine Unmenge von Objekten haben, die HasId oder andere solche Schnittstellen problemlos implementieren können, finde ich es sehr angenehm, damit zu arbeiten.

1
Scott Strang

Höchsteffizient? Im Grunde einfach iterieren und zur Liste hinzufügen. Sie müssen sich jeden Artikel ansehen. 

Collection<Long> ids = new LinkedList<Long>();
for (Entity e : entities) {
    ids.add(e.id);
}

Wenn Sie Java 1.8 verwenden können, können Sie Folgendes tun:

entities.forEach((e) -> ids.add(e.id));
1
kmera

Konvertieren Sie die Liste stattdessen in einen Stream und dann zurück zur Liste

Ich werde weiter unten empfehlen

Collection-IDs = neue LinkedList (); Entity.forEach ((e) -> ids.add (e.id));