POO-ITBA / 2024_01

Consultas 1C 2024
0 stars 0 forks source link

Ejercicio 3 de Repaso Segundo Parcial #16

Open santinopepe opened 5 months ago

santinopepe commented 5 months ago

Hola, tenia una duda si estaba bien esta resolucion y que se podria mejorar. Tambien tengo mis dudas en la funcion getValue en la parte que hago current - 1, seria mejor incrmentar current en ese momento? Desde ya muchas gracias!


public class FilteredKeyMapIterator<K, V> implements Iterator<K> {
    private final Map<K,V> filterMap = new HashMap<>();
    private int current = 0;
    private List<K> keys =  new ArrayList<>();

    public FilteredKeyMapIterator(Map<K,V> map,Predicate<K> predicate){
        for(K key : map.keySet()){
            if(predicate.test(key)){
                filterMap.put(key,map.get(key));
            }
        }
        keys.addAll(filterMap.keySet());
    }

    @Override
    public boolean hasNext() {
        return current < keys.size();
    }

    @Override
    public K next() {
        if (!hasNext()){
            throw new NoSuchElementException();
        }
        return keys.get(current++);
    }

    public V getValue(){
        return filterMap.get(keys.get(current-1));
    }

}
fmeola commented 5 months ago

Hola @santinopepe

La implementación es correcta. En principio habría que evitar copiar información (en este caso sería mejor acceder directamente a los valores del mapa) pero en estos casos te simplifica el hecho de que next no tenga que recurrir en un ciclo (porque en cada invocación a next no sabés si va a haber un elemento que cumpla).

Lo que tenés que corregir es que getValue lance una NoSuchElementException si current es 0 porque estarías accediendo a la posición -1 de keys y no corresponde.

Menciono también que no necesitás la variable keys, podés usar el iterador de las claves de filterMap directamente. Te dejo otra versión:

public class FilteredKeyMapIterator<K, V> implements Iterator<K> {

    private final Map<K,V> filterMap = new HashMap<>();

    private final Iterator<K> keyIterator;
    private V currentValue;

    public FilteredKeyMapIterator(Map<K,V> map, Predicate<K> predicate){
        for(K key : map.keySet()){
            if(predicate.test(key)){
                filterMap.put(key,map.get(key));
            }
        }
        keyIterator = filterMap.keySet().iterator();
    }

    @Override
    public boolean hasNext() {
        return keyIterator.hasNext();
    }

    @Override
    public K next() {
        if (!hasNext()){
            throw new NoSuchElementException();
        }
        K key = keyIterator.next();
        currentValue = filterMap.get(key);
        return key;
    }

    public V getValue(){
        if(currentValue == null){
            throw new NoSuchElementException();
        }
        return currentValue;
    }

}

Notar que en esta versión cada invocación a getValue no implica un acceso al mapa, para conseguir el valor sólo se accede una vez en el next cuando cambia la clave y se guarda ese valor

santinopepe commented 5 months ago

Muchas Gracias!