Difference between revisions of "Classes Internas (Java)/Exercício 01: Interfaces java.lang.Comparable e java.util.Comparator"

From Wiki**3

< Classes Internas (Java)
 
(7 intermediate revisions by the same user not shown)
Line 2: Line 2:
 
== Problema ==
 
== Problema ==
  
# Considere a tabela da Aula Pr&aacute;tica 04. Redefina a classe como sendo compar&aacute;vel. Diz-se que uma tabela &eacute; menor/igual/maior que outra quando se verificar a rela&ccedil;&atilde;o menor/igual/maior entre as somas dos elementos de cada uma.
+
# Considere a tabela da [[Polimorfismo, Interfaces, Classes Abstractas/Exercício 02: Tabelas e Predicados|Aula Prática 05]]. Redefina a classe como sendo compar&aacute;vel. Diz-se que uma tabela &eacute; menor/igual/maior que outra quando se verificar a rela&ccedil;&atilde;o menor/igual/maior entre as somas dos elementos de cada uma.
 
# Considere ainda o caso da al&iacute;nea anterior. Defina agora dois comparadores (devem ser implementados como classes internas da tabela) que estabelecem as rela&ccedil;&otilde;es de compara&ccedil;&atilde;o relativamente (i) aos m&aacute;ximos das tabelas e (ii) ao n&uacute;mero de elementos (independentemente dos valores).
 
# Considere ainda o caso da al&iacute;nea anterior. Defina agora dois comparadores (devem ser implementados como classes internas da tabela) que estabelecem as rela&ccedil;&otilde;es de compara&ccedil;&atilde;o relativamente (i) aos m&aacute;ximos das tabelas e (ii) ao n&uacute;mero de elementos (independentemente dos valores).
 
# Considere agora, em lugar de tabelas de inteiros, que as tabelas cont&ecirc;m gatos (classe definida acima). Altere o c&oacute;digo da al&iacute;nea 2(i) para que funcione com as tabelas de gatos.
 
# Considere agora, em lugar de tabelas de inteiros, que as tabelas cont&ecirc;m gatos (classe definida acima). Altere o c&oacute;digo da al&iacute;nea 2(i) para que funcione com as tabelas de gatos.
Line 12: Line 12:
 
Para este caso, é necessário definir a classe Table como implementando Comparable.
 
Para este caso, é necessário definir a classe Table como implementando Comparable.
  
<java5>
+
{{CollapsedCode|Ficheiro '''Table.java'''|
 +
<source lang="java">
 
/**
 
/**
 
  * A table holding a fixed number of integers.
 
  * A table holding a fixed number of integers.
  *  
+
  *
 
  * It is possible to verify certain predicates against the table's contents.
 
  * It is possible to verify certain predicates against the table's contents.
 
  */
 
  */
 
public class Table implements Comparable<Table> {
 
public class Table implements Comparable<Table> {
  
/**
+
    /**
* Space for a fixed number of integers.
+
    * Space for a fixed number of integers.
*/
+
    */
int _vector[];
+
    int _vector[];
  
/**
+
    /**
* @param nInts
+
    * @param nInts
*            number of integers to store.
+
    *            number of integers to store.
*/
+
    */
public Table(int nInts) {
+
    public Table(int nInts) {
_vector = new int[nInts];
+
        _vector = new int[nInts];
}
+
    }
  
/**
+
    /**
* FIXME: insert checks to ensure position is within range.
+
    * FIXME: insert checks to ensure position is within range.
*  
+
    *
* @param position
+
    * @param position
*            position to define
+
    *            position to define
* @return value at position
+
    * @return value at position
*/
+
    */
public int getValue(int position) {
+
    public int getValue(int position) {
return _vector[position];
+
        return _vector[position];
}
+
    }
  
/**
+
    /**
* FIXME: insert checks to ensure position is within range.
+
    * FIXME: insert checks to ensure position is within range.
*  
+
    *
* @param position
+
    * @param position
*            position to define
+
    *            position to define
* @param value
+
    * @param value
*            value to set
+
    *            value to set
*/
+
    */
public void setValue(int position, int value) {
+
    public void setValue(int position, int value) {
_vector[position] = value;
+
        _vector[position] = value;
}
+
    }
  
/**
+
    /**
* Set all positions to the same value.
+
    * Set all positions to the same value.
*  
+
    *
* @param value
+
    * @param value
*            value to set
+
    *            value to set
*/
+
    */
public void setAll(int value) {
+
    public void setAll(int value) {
for (int position = 0; position < _vector.length; position++)
+
        for (int position = 0; position < _vector.length; position++)
_vector[position] = value;
+
            _vector[position] = value;
}
+
    }
  
/**
+
    /**
* @param predicate
+
    * @param predicate
*            the predicate to validate.
+
    *            the predicate to validate.
* @return true, if the predicate is valid for at least one position; false,
+
    * @return true, if the predicate is valid for at least one position; false,
*        otherwise.
+
    *        otherwise.
*/
+
    */
public boolean contains(SelectionPredicate predicate) {
+
    public boolean contains(SelectionPredicate predicate) {
for (int position = 0; position < _vector.length; position++)
+
        for (int position = 0; position < _vector.length; position++)
if (predicate.ok(_vector[position]))
+
            if (predicate.ok(_vector[position]))
return true;
+
                return true;
return false;
+
        return false;
}
+
    }
  
/**
+
    /**
* This method makes it easy to get the sum of all elements. As with the
+
    * This method makes it easy to get the sum of all elements. As with the
* predicate, this type of algorithm could also be provided from outside:
+
    * predicate, this type of algorithm could also be provided from outside:
* instead of a selector, a collector would have to be provided.
+
    * instead of a selector, a collector would have to be provided.
*  
+
    *
* @return sum of all elements.
+
    * @return sum of all elements.
*/
+
    */
public int getSum() {
+
    public int getSum() {
int sum = 0;
+
        int sum = 0;
for (int i : _vector)
+
        for (int i : _vector)
sum += i;
+
            sum += i;
return sum;
+
        return sum;
}
+
    }
  
/**
+
    /**
* @see java.lang.Comparable#compareTo(java.lang.Object)
+
    * @see java.lang.Comparable#compareTo(java.lang.Object)
*/
+
    */
@Override
+
    @Override
public int compareTo(Table other) {
+
    public int compareTo(Table other) {
return getSum() - other.getSum();
+
        return getSum() - other.getSum();
}
+
    }
 
}
 
}
</java5>
+
</source>
 +
}}
  
 
== 2. Comparadores de Máximo e Comprimento ==
 
== 2. Comparadores de Máximo e Comprimento ==
 +
 +
{{CollapsedCode|Diagrama de classes|
 +
(por lapso, o diagrama UML omite o método '''contains''', mas o resto está correcto)
 +
[[Image:PO-Interfaces-Comparable-Comparator.png|600px]]
 +
}}
  
 
Notar que as classes internas são static e que apenas estão contidas na classe Table por conveniência de ocultação de código.
 
Notar que as classes internas são static e que apenas estão contidas na classe Table por conveniência de ocultação de código.
  
<java5>
+
{{CollapsedCode|Ficheiro '''Table.java'''|
 +
<source lang="java">
 
import java.util.Comparator;
 
import java.util.Comparator;
  
 
/**
 
/**
 
  * A table holding a fixed number of integers.
 
  * A table holding a fixed number of integers.
  *  
+
  *
 
  * It is possible to verify certain predicates against the table's contents.
 
  * It is possible to verify certain predicates against the table's contents.
 
  */
 
  */
 
public class Table implements Comparable<Table> {
 
public class Table implements Comparable<Table> {
  
/**
+
    /**
* A comparator for tables: based on maximum value.
+
    * A comparator for tables: based on maximum value.
*  
+
    *
* Use as: Table.MAX_COMPARATOR
+
    * Use as: Table.MAX_COMPARATOR
*/
+
    */
public final static Comparator<Table> MAX_COMPARATOR = new MaxComparator();
+
    public final static Comparator<Table> MAX_COMPARATOR = new MaxComparator();
+
   
/**
+
    /**
* A comparator for tables: based on length.
+
    * A comparator for tables: based on length.
*  
+
    *
* Use as: Table.LENGTH_COMPARATOR
+
    * Use as: Table.LENGTH_COMPARATOR
*/
+
    */
public final static Comparator<Table> LENGTH_COMPARATOR = new LengthComparator();
+
    public final static Comparator<Table> LENGTH_COMPARATOR = new LengthComparator();
  
/**
+
    /**
* This is a private class implementing the comparator.
+
    * This is a private class implementing the comparator.
*/
+
    */
private static class MaxComparator implements Comparator<Table> {
+
    private static class MaxComparator implements Comparator<Table> {
  
/**
+
        /**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+
        * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
+
        */
@Override
+
        @Override
public int compare(Table table1, Table table2) {
+
        public int compare(Table table1, Table table2) {
return table1.getMax() - table2.getMax();
+
            return table1.getMax() - table2.getMax();
}
+
        }
+
       
}
+
    }
  
/**
+
    /**
* This is a private class implementing the comparator.
+
    * This is a private class implementing the comparator.
*/
+
    */
private static class LengthComparator implements Comparator<Table> {
+
    private static class LengthComparator implements Comparator<Table> {
  
/**
+
        /**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+
        * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
+
        */
@Override
+
        @Override
public int compare(Table table1, Table table2) {
+
        public int compare(Table table1, Table table2) {
return table1.getLength() - table2.getLength();
+
            return table1.getLength() - table2.getLength();
}
+
        }
+
       
}
+
    }
+
   
/**
+
    /**
* Space for a fixed number of integers.
+
    * Space for a fixed number of integers.
*/
+
    */
int _vector[];
+
    int _vector[];
  
/**
+
    /**
* @param nInts
+
    * @param nInts
*            number of integers to store.
+
    *            number of integers to store.
*/
+
    */
public Table(int nInts) {
+
    public Table(int nInts) {
_vector = new int[nInts];
+
        _vector = new int[nInts];
}
+
    }
  
/**
+
    /**
* FIXME: insert checks to ensure position is within range.
+
    * FIXME: insert checks to ensure position is within range.
*  
+
    *
* @param position
+
    * @param position
*            position to define
+
    *            position to define
* @return value at position
+
    * @return value at position
*/
+
    */
public int getValue(int position) {
+
    public int getValue(int position) {
return _vector[position];
+
        return _vector[position];
}
+
    }
  
/**
+
    /**
* FIXME: insert checks to ensure position is within range.
+
    * FIXME: insert checks to ensure position is within range.
*  
+
    *
* @param position
+
    * @param position
*            position to define
+
    *            position to define
* @param value
+
    * @param value
*            value to set
+
    *            value to set
*/
+
    */
public void setValue(int position, int value) {
+
    public void setValue(int position, int value) {
_vector[position] = value;
+
        _vector[position] = value;
}
+
    }
  
/**
+
    /**
* Set all positions to the same value.
+
    * Set all positions to the same value.
*  
+
    *
* @param value
+
    * @param value
*            value to set
+
    *            value to set
*/
+
    */
public void setAll(int value) {
+
    public void setAll(int value) {
for (int position = 0; position < _vector.length; position++)
+
        for (int position = 0; position < _vector.length; position++)
_vector[position] = value;
+
            _vector[position] = value;
}
+
    }
  
/**
+
    /**
* @param predicate
+
    * @param predicate
*            the predicate to validate.
+
    *            the predicate to validate.
* @return true, if the predicate is valid for at least one position; false,
+
    * @return true, if the predicate is valid for at least one position; false,
*        otherwise.
+
    *        otherwise.
*/
+
    */
public boolean contains(SelectionPredicate predicate) {
+
    public boolean contains(SelectionPredicate predicate) {
for (int position = 0; position < _vector.length; position++)
+
        for (int position = 0; position < _vector.length; position++)
if (predicate.ok(_vector[position]))
+
            if (predicate.ok(_vector[position]))
return true;
+
                return true;
return false;
+
        return false;
}
+
    }
  
/**
+
    /**
* This method makes it easy to get the sum of all elements. As with the
+
    * This method makes it easy to get the sum of all elements. As with the
* predicate, this type of algorithm could also be provided from outside:
+
    * predicate, this type of algorithm could also be provided from outside:
* instead of a selector, a collector would have to be provided.
+
    * instead of a selector, a collector would have to be provided.
*  
+
    *
* @return sum of all elements.
+
    * @return sum of all elements.
*/
+
    */
public int getSum() {
+
    public int getSum() {
int sum = 0;
+
        int sum = 0;
for (int i : _vector)
+
        for (int i : _vector)
sum += i;
+
            sum += i;
return sum;
+
        return sum;
}
+
    }
  
/**
+
    /**
* This method makes it easy to get the maximum of all elements. As with the
+
    * This method makes it easy to get the maximum of all elements. As with the
* predicate, this type of algorithm could also be provided from outside:
+
    * predicate, this type of algorithm could also be provided from outside:
* instead of a selector, a collector would have to be provided.
+
    * instead of a selector, a collector would have to be provided.
*  
+
    *
* @return maximum value in the table.
+
    * @return maximum value in the table.
*/
+
    */
public int getMax() {
+
    public int getMax() {
int max = _vector[0];
+
        int max = _vector[0];
for (int i : _vector)
+
        for (int i : _vector)
if (i > max)
+
            if (i > max)
max = i;
+
                max = i;
return max;
+
        return max;
}
+
    }
  
/**
+
    /**
* This method makes it easy to get the number of elements. As with the
+
    * This method makes it easy to get the number of elements. As with the
* predicate, this type of algorithm could also be provided from outside:
+
    * predicate, this type of algorithm could also be provided from outside:
* instead of a selector, a collector would have to be provided.
+
    * instead of a selector, a collector would have to be provided.
*  
+
    *
* In this case, we are not actually iterating, since it is much easier and
+
    * In this case, we are not actually iterating, since it is much easier and
* efficient to access the length attribute.
+
    * efficient to access the length attribute.
*  
+
    *
* @return length of table.
+
    * @return length of table.
*/
+
    */
public int getLength() {
+
    public int getLength() {
return _vector.length;
+
        return _vector.length;
}
+
    }
  
/**
+
    /**
* @see java.lang.Comparable#compareTo(java.lang.Object)
+
    * @see java.lang.Comparable#compareTo(java.lang.Object)
*/
+
    */
@Override
+
    @Override
public int compareTo(Table other) {
+
    public int compareTo(Table other) {
return getSum() - other.getSum();
+
        return getSum() - other.getSum();
}
+
    }
+
   
 
}
 
}
</java5>
+
</source>
 +
}}
  
 
== 3. Comparador de Tabelas de Gatos ==
 
== 3. Comparador de Tabelas de Gatos ==
Line 282: Line 291:
 
== Exemplo de Aplicação ==
 
== Exemplo de Aplicação ==
  
<java5>
+
{{CollapsedCode|Ficheiro '''Application.java'''|
/**
+
<source lang="java">
* Sample uses.
 
*/
 
 
public class Application {
 
public class Application {
  
/**
+
    /**
* @param args
+
    * @param args
*/
+
    */
public static void main(String[] args) {
+
    public static void main(String[] args) {
Table t1 = new Table(3); // table with 3 integers
+
        Table t1 = new Table(3); // table with 3 integers
Table t2 = new Table(3); // table with 3 integers
+
        Table t2 = new Table(3); // table with 3 integers
  
t1.setAll(3);
+
        t1.setAll(3);
t2.setAll(90);
+
        t2.setAll(90);
+
       
System.out.println(t1.compareTo(t2));  // <0
+
        System.out.println(t1.compareTo(t2));  // <0
System.out.println(Table.MAX_COMPARATOR.compare(t1, t2));    // <0
+
        System.out.println(Table.MAX_COMPARATOR.compare(t1, t2));    // <0
System.out.println(Table.MAX_COMPARATOR.compare(t1, t1));    //  0
+
        System.out.println(Table.MAX_COMPARATOR.compare(t1, t1));    //  0
System.out.println(Table.MAX_COMPARATOR.compare(t2, t2));    //  0
+
        System.out.println(Table.MAX_COMPARATOR.compare(t2, t2));    //  0
System.out.println(Table.MAX_COMPARATOR.compare(t2, t1));    // >0
+
        System.out.println(Table.MAX_COMPARATOR.compare(t2, t1));    // >0
System.out.println(Table.LENGTH_COMPARATOR.compare(t1, t2));  // 0 (same length)
+
        System.out.println(Table.LENGTH_COMPARATOR.compare(t1, t2));  // 0 (same length)
+
       
}
+
    }
  
 
}
 
}
</java5>
+
</source>
 +
}}
  
 
[[category:Ensino]]
 
[[category:Ensino]]
 
[[category:PO]]
 
[[category:PO]]
[[category:PO Exemplos]
+
[[category:PO Exemplos]]

Latest revision as of 21:11, 8 November 2018

Problema

  1. Considere a tabela da Aula Prática 05. Redefina a classe como sendo comparável. Diz-se que uma tabela é menor/igual/maior que outra quando se verificar a relação menor/igual/maior entre as somas dos elementos de cada uma.
  2. Considere ainda o caso da alínea anterior. Defina agora dois comparadores (devem ser implementados como classes internas da tabela) que estabelecem as relações de comparação relativamente (i) aos máximos das tabelas e (ii) ao número de elementos (independentemente dos valores).
  3. Considere agora, em lugar de tabelas de inteiros, que as tabelas contêm gatos (classe definida acima). Altere o código da alínea 2(i) para que funcione com as tabelas de gatos.

Solução

1. Tabela comparável

Para este caso, é necessário definir a classe Table como implementando Comparable.

Ficheiro Table.java
/**
 * A table holding a fixed number of integers.
 *
 * It is possible to verify certain predicates against the table's contents.
 */
public class Table implements Comparable<Table> {

    /**
     * Space for a fixed number of integers.
     */
    int _vector[];

    /**
     * @param nInts
     *            number of integers to store.
     */
    public Table(int nInts) {
        _vector = new int[nInts];
    }

    /**
     * FIXME: insert checks to ensure position is within range.
     *
     * @param position
     *            position to define
     * @return value at position
     */
    public int getValue(int position) {
        return _vector[position];
    }

    /**
     * FIXME: insert checks to ensure position is within range.
     *
     * @param position
     *            position to define
     * @param value
     *            value to set
     */
    public void setValue(int position, int value) {
        _vector[position] = value;
    }

    /**
     * Set all positions to the same value.
     *
     * @param value
     *            value to set
     */
    public void setAll(int value) {
        for (int position = 0; position < _vector.length; position++)
            _vector[position] = value;
    }

    /**
     * @param predicate
     *            the predicate to validate.
     * @return true, if the predicate is valid for at least one position; false,
     *         otherwise.
     */
    public boolean contains(SelectionPredicate predicate) {
        for (int position = 0; position < _vector.length; position++)
            if (predicate.ok(_vector[position]))
                return true;
        return false;
    }

    /**
     * This method makes it easy to get the sum of all elements. As with the
     * predicate, this type of algorithm could also be provided from outside:
     * instead of a selector, a collector would have to be provided.
     *
     * @return sum of all elements.
     */
    public int getSum() {
        int sum = 0;
        for (int i : _vector)
            sum += i;
        return sum;
    }

    /**
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    @Override
    public int compareTo(Table other) {
        return getSum() - other.getSum();
    }
}

2. Comparadores de Máximo e Comprimento

Diagrama de classes

(por lapso, o diagrama UML omite o método contains, mas o resto está correcto) PO-Interfaces-Comparable-Comparator.png

Notar que as classes internas são static e que apenas estão contidas na classe Table por conveniência de ocultação de código.

Ficheiro Table.java
import java.util.Comparator;

/**
 * A table holding a fixed number of integers.
 *
 * It is possible to verify certain predicates against the table's contents.
 */
public class Table implements Comparable<Table> {

    /**
     * A comparator for tables: based on maximum value.
     *
     * Use as: Table.MAX_COMPARATOR
     */
    public final static Comparator<Table> MAX_COMPARATOR = new MaxComparator();
    
    /**
     * A comparator for tables: based on length.
     *
     * Use as: Table.LENGTH_COMPARATOR
     */
    public final static Comparator<Table> LENGTH_COMPARATOR = new LengthComparator();

    /**
     * This is a private class implementing the comparator.
     */
    private static class MaxComparator implements Comparator<Table> {

        /**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        @Override
        public int compare(Table table1, Table table2) {
            return table1.getMax() - table2.getMax();
        }
        
    }

    /**
     * This is a private class implementing the comparator.
     */
    private static class LengthComparator implements Comparator<Table> {

        /**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        @Override
        public int compare(Table table1, Table table2) {
            return table1.getLength() - table2.getLength();
        }
        
    }
    
    /**
     * Space for a fixed number of integers.
     */
    int _vector[];

    /**
     * @param nInts
     *            number of integers to store.
     */
    public Table(int nInts) {
        _vector = new int[nInts];
    }

    /**
     * FIXME: insert checks to ensure position is within range.
     *
     * @param position
     *            position to define
     * @return value at position
     */
    public int getValue(int position) {
        return _vector[position];
    }

    /**
     * FIXME: insert checks to ensure position is within range.
     *
     * @param position
     *            position to define
     * @param value
     *            value to set
     */
    public void setValue(int position, int value) {
        _vector[position] = value;
    }

    /**
     * Set all positions to the same value.
     *
     * @param value
     *            value to set
     */
    public void setAll(int value) {
        for (int position = 0; position < _vector.length; position++)
            _vector[position] = value;
    }

    /**
     * @param predicate
     *            the predicate to validate.
     * @return true, if the predicate is valid for at least one position; false,
     *         otherwise.
     */
    public boolean contains(SelectionPredicate predicate) {
        for (int position = 0; position < _vector.length; position++)
            if (predicate.ok(_vector[position]))
                return true;
        return false;
    }

    /**
     * This method makes it easy to get the sum of all elements. As with the
     * predicate, this type of algorithm could also be provided from outside:
     * instead of a selector, a collector would have to be provided.
     *
     * @return sum of all elements.
     */
    public int getSum() {
        int sum = 0;
        for (int i : _vector)
            sum += i;
        return sum;
    }

    /**
     * This method makes it easy to get the maximum of all elements. As with the
     * predicate, this type of algorithm could also be provided from outside:
     * instead of a selector, a collector would have to be provided.
     *
     * @return maximum value in the table.
     */
    public int getMax() {
        int max = _vector[0];
        for (int i : _vector)
            if (i > max)
                max = i;
        return max;
    }

    /**
     * This method makes it easy to get the number of elements. As with the
     * predicate, this type of algorithm could also be provided from outside:
     * instead of a selector, a collector would have to be provided.
     *
     * In this case, we are not actually iterating, since it is much easier and
     * efficient to access the length attribute.
     *
     * @return length of table.
     */
    public int getLength() {
        return _vector.length;
    }

    /**
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    @Override
    public int compareTo(Table other) {
        return getSum() - other.getSum();
    }
    
}

3. Comparador de Tabelas de Gatos

(a publicar)

Exemplo de Aplicação

Ficheiro Application.java
public class Application {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Table t1 = new Table(3); // table with 3 integers
        Table t2 = new Table(3); // table with 3 integers

        t1.setAll(3);
        t2.setAll(90);
        
        System.out.println(t1.compareTo(t2));  // <0
        System.out.println(Table.MAX_COMPARATOR.compare(t1, t2));     // <0
        System.out.println(Table.MAX_COMPARATOR.compare(t1, t1));     //  0
        System.out.println(Table.MAX_COMPARATOR.compare(t2, t2));     //  0
        System.out.println(Table.MAX_COMPARATOR.compare(t2, t1));     // >0
        System.out.println(Table.LENGTH_COMPARATOR.compare(t1, t2));  // 0 (same length)
        
    }

}