web-dev-qa-db-fra.com

Le moyen le plus efficace de trouver la collection de tous les identifiants dans une collection d'entités

J'ai une entité:

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

    public long getId() {
        return id;
    }

    public String getData() {
        return data;
    }
}

et une collection d'entités:

Collection<Entity> entities= ...

Quel est le moyen le plus efficace de trouver le Collection<Long> de tous les identifiants dans entities?

15
rapt

En supposant que vous avez

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;
    }
}

En Java 8, vous pouvez écrire

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);

empreintes

[1, 10, 100]

Comme vous pouvez l’imaginer, cela est plutôt moche dans Java 7 ou moins. Notez que Entity.getId, lorsqu'il est appliqué à map (), signifie que cette méthode est appelée pour chaque élément.

Maintenant, la partie la plus intéressante est que vous pouvez le faire.

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

Dans dans la plupart des cas , utiliser un flux parallèle nuit aux performances, mais rend l’essai et la vision incroyablement faciles (peut-être trop facile;)


Le moyen le plus efficace est d’avoir ou de construire une carte.

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

Vous n'obtiendrez rien de moins que:

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

Je suppose que tous les moyens iraient sur la collection

Pas nécessairement. Cela crée une collection qui est directement sauvegardée par la collection d'entités sous-jacentes (les modifications futures apportées à la collection d'entités apparaissent dans la collection ids):

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

Je ne sais pas si c'est forcément le plus efficace, mais pour les versions antérieures à Java 8, je me suis habitué à utiliser les interfaces de propriété décrites ci-dessous: http://blog.cgdecker.com/2010/06/property -interfaces-and-guava.html

Comme décrit dans l'article du blog, vous auriez une interface simple nommée quelque chose comme HasId:

public interface HasId {
    long getId();
}

Votre classe d'entité ressemblerait à ceci:

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

    public long getId() {
        return id;
    }

    public String getData() {
        return data;
    }
}

et vous auriez une fonction simple comme celle-ci quelque part:

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

Enfin, pour en profiter:

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

C'est excessif si vous n'en avez besoin que pour une seule chose, mais si vous avez une tonne d'objets pouvant implémenter correctement HasId ou d'autres interfaces de ce type, je trouve le travail très agréable.

1
Scott Strang

Le plus efficace? En gros, il suffit de parcourir et d’ajouter à la liste. Vous devez regarder chaque article. 

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

Ou, si vous pouvez utiliser Java 1.8, vous pouvez faire quelque chose comme:

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

Au lieu de cela, convertir la liste en flux, puis revenir à la liste

Je recommanderai ci-dessous

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

0