Lista sem repetição

Bom dia,
alguém pode me dar uma dica. Estou usando um objeto List pra armazenar uma lista de objetos de banco de dados, mas surgiu a necessidade de impedir a repetição de elementos. Tem alguma técnica pra eu fazer isso, algum objeto compativel com list que facilite a lista sem repetição?

Um abraço.

use um Set ao inves de um List.

[]'s

Lembrando que, ao usar Set, voce precisa implementar os metodos equals() e hashCode()

Rafael

dependendo do Set nao vai precisar de hashCode, mas ja eh uma boa.
crisadias, use java.util.HashSet, interfaceado pela Set como ja falaram.

Olá,

O set é mais indicado, mas existe ainda o List.contains(Object o), que diz se um objeto já está na lista. Acho que para isto é preciso reescrever equals e hashCode().

Márcio

Pessoal,
posso então continuar usando o List e fazer a comparação com .contains desde que reescreva o método equals() do meu objeto, certo? É a melhor solução no caso.

Valeu pela ajuda.

Lembre-se que para reescrever equals() e hashCode() você tem que garantir algumas coisas para que sua classe fique consistente.
Objetos considerados iguais pelo método equals() precisam necessariamente possuir o mesmo hashCode().
Objetos diferente não necessariamente precisam ter hashCode() diferentes.

[quote=Paulo Silveira]dependendo do Set nao vai precisar de hashCode, mas ja eh uma boa.
crisadias, use java.util.HashSet, interfaceado pela Set como ja falaram.[/quote]

Dependendo do Set? Hmm, ou ele é feito com hashing e precisa do hashCode, ou é feito usando arvores, ai precisa do Comparable, um contrato beeeem mais dificil de implementar.

Alguém precisa disponibilizar aqui um Comparator “genérico”. Alguma coisa que fosse usada assim:

Digamos que você tivesse um TreeSet de ClienteVO, onde ClienteVO tem os seguintes atributos: double salario, String nome, String sobrenome.

SortedSet minhaListaOrdenada = new TreeSet (new ComparatorGenerico (new String[]{"sobrenome", "nome"}));
minhaListaOrdenada.add (new ClienteVO ("José", "Aparecido", 100.0));
minhaListaOrdenada.add (new ClienteVO ("James", "Gosling", 200.0));

SortedSet minhaListaOrdenada2 = new TreeSet (new ComparatorGenerico (new String[]{"-salario", "+sobrenome"}));
// "-salario" porque queremos algo parecido com "ORDER BY SALARIO DESC, BY SOBRENOME ASC"
minhaListaOrdenada2.add (new ClienteVO ("Jonathan", "Schwartz", 1000.0));
minhaListaOrdenada2.add (new ClienteVO ("James", "Gosling", 200.0));

Não é difícil de escrever (nada que um pouco de reflection não resolva) mas dá trabalho…

Fiz algo semelhante (precisa de refatoração @.@)

class PropertyComparator< T > implements Comparator
{
	private String fieldToCompare;
	private Boolean ascending;

	public PropertyComparator( String fieldToCompare, Boolean ascending )
	{
		this.fieldToCompare = fieldToCompare;
		this.ascending = ascending;
	}

	public int compare( Object o1, Object o2 )
	{
		int returnValue = 0;
		boolean inverse = ( ascending != null && !ascending.booleanValue() );

		if( o1 == null || o2 == null )
		{
			if( o1 == null && o2 == null )
				returnValue = 0;
			else if( o1 == null )
				returnValue = -1;
			else if( o2 == null )
				returnValue = 1;
			
			if( inverse )
				returnValue *= -1;

			return returnValue;
		}

		T p1 = ( T ) o1;
		T p2 = ( T ) o2;

		Comparable value1 = ( Comparable ) ReflectionUtils.getFieldValue( p1,
			fieldToCompare );
		Comparable value2 = ( Comparable ) ReflectionUtils.getFieldValue( p2,
			fieldToCompare );

		if( value1 == null && value2 == null )
			returnValue = 0;
		else if( value1 == null )
			returnValue = -1;
		else if( value2 == null )
			returnValue = 1;
		else if( value1 instanceof String )
			returnValue = ( StringUtils.removeAccents( value1 ) ).compareToIgnoreCase( StringUtils.removeAccents( value2 ) );
		else
			returnValue = value1.compareTo( value2 );

		if( inverse )
			returnValue *= -1;

		return returnValue;
	}
}

public class ReflectionUtils
{
	public static Object getFieldValue( Object toInvoke, String fieldName )
	{
		Object value = null;
		try
		{
			Class klass = toInvoke.getClass();
			
			Field[] fields = klass.getDeclaredFields();
			Field field = null;
			for( int i = 0; i < fields.length; i++ )
			{

				if( fields[ i ].getName().equals( fieldName ) )
				{
					field = fields[ i ];
					break;
				}
			}
			
			if( field == null )
				throw new NoSuchFieldException();

			changeFieldToPublic( field );

			value = field.get( toInvoke );
		}
		catch( Exception e )
		{
			logger.error( ReflectionUtils.class.getSimpleName()
					+ ".getFieldValue(Object toInvoke = " + toInvoke
					+ ", String fieldName = " + fieldName + ") - exception", e );
		}

		return value;
	}
	
	public static Field changeFieldToPublic( Field field )
	{
		if( field.getModifiers() != Field.PUBLIC )
			field.setAccessible( true );
		
		return field;
	}
}

ops escrevi no topico errado… mod poderia apagar isso aki?

Bom dia,

Estou tentando implementar um Comparator genérico ond eu passo
um vetor de strings ou talvez uma lista de strings que são os atributos pelos quais eu vou ordenar.
Já tenho um comparator que é usado apenas para um atributo:

public class ObjectComparator implements Comparator
{
    /** propertyToCompare to attribute */
    private String propertyToCompare;

    /**
     * Creates a new ObjectComparator object.
     *
     * @param propertyToCompare property of object to compare
     */
    public ObjectComparator(String propertyToCompare)
    {
        this.propertyToCompare = propertyToCompare;
    }

    /**
     * Compares the first object with second object using the property defined
     * in the constructor
     *
     * @param o1 first object
     * @param o2 second object
     *
     * @return int
     */
    public int compare(Object o1, Object o2)
    {
        int returnValue = 0;

        if ((o1 == null) || (o2 == null))
        {
            if ((o1 == null) && (o2 == null))
            {
                returnValue = 0;
            }
            else if (o1 == null)
            {
                returnValue = -1;
            }
            else if (o2 == null)
            {
                returnValue = 1;
            }

            return returnValue;
        }
        
		Object objValue1 = ObjectReflection.getFieldValue(o1,
				propertyToCompare);

		Object objValue2 = ObjectReflection.getFieldValue(o2,
				propertyToCompare);

        if ((objValue1 == null) && (objValue2 == null))
        {
            returnValue = 0;
        }
        else if (objValue1 == null)
        {
            returnValue = -1;
        }
        else if (objValue2 == null)
        {
            returnValue = 1;
        }
        else
        {
			Comparable value1 = null;
			Comparable value2 = null;
			
			if (objValue1 instanceof Calendar)
			{
				value1 = (Comparable) ((Calendar) objValue1).getTime();
			}
			else
			{
				value1 = (Comparable) objValue1;	
			}

			if (objValue2 instanceof Calendar)
			{
				value2 = (Comparable) ((Calendar) objValue2).getTime();
			}
			else
			{
				value2 = (Comparable) objValue2;	
			}
        	
            returnValue = value1.compareTo(value2);
        }

        return returnValue;
    }

Porém, como fazer daki em diante?
Se alguém puder dar uma dica…

valew

Blz?

encontrei uma solução muito legal sobre fazer este tipo de ordenação,
usando o ComparatorChain do org.apache.commons.collections.comparators.

Segue um exemplo:

		Comparator objName = new ObjectComparator("name");
		Comparator objId = new ObjectComparator("objectId");
		
		ComparatorChain comp = new ComparatorChain();
		comp.addComparator(objName);
		comp.addComparator(objId);

Ond primeiramente ordena por name, depois por ojectId.