Boa noite pessoal , estou com um problema gostaria de saber…
Como faço p retornar de um arraylist o menor valor e unico ?
Menor valor e unico de um arraylist
13 Respostas
Bom, pelo visto o que você precisa não é um ArrayList. Se você detalhar melhor poderíamos ajudar de uma maneira mais adequada.
public class Carro implements Produto {
private String descricao;
Cotains
List<Lance>lances=new ArrayList <Lance>();
public Carro(String descricao) {
this.descricao = descricao;
}
@Override
public boolean Oferta(Lance lance) {
return lances.add(lance);
}
//retorna lance vencedor = menor valor e unico
// nao consigo retornar valor unico aq
@Override
public Lance finalizar() {
double menor = lances.size();
for (Lance lance : lances) {
if(lance.getValor() < menor){
menor = lance.getValor();
System.out.println(menor);
return lance;
}
}
return null;
}
@Override
public String getDescricao() {
return descricao;
}
//deve receber um lance e informar se o lance já foi efetuado
public boolean lanceJaFeito(Lance lance) {
if (lances.contains(lance)) {
System.out.println("Lance ja efetuado : " +lance);
return true;
} else {
System.out.println("Lance disponivel : " +lance);
return false;
}
}
}
Acho que isso deve resolver seu problema:
public int finalizar(int[] lances) {
int ganhador = Integer.MAX_VALUE;
for (int lance : lances) {
if (ehUnico(lances, lance)) {
if (lance < ganhador) {
ganhador = lance;
}
}
}
return ganhador;
}
protected boolean ehUnico(int[] valores, int v) {
boolean visitouProprio = false;
for (int x : valores) {
if (!visitouProprio && v == x) {
visitouProprio = true;
continue;
}
if (v == x)
return false;
}
return true;
}
Adapte para sua situação… é um problema de lógica interessante que exige realmente um grande raciocínio. Fiz testes de unidade para conseguir resolver esse problema mais rapidamente e aparentemente ele resolve. Faça muitos testes para ter certeza que o código está legal 
Abraços
Outra alternativa(um tanto diferente do habitual):
HashMap<Integer, Integer> lances = new HashMap<Integer, Integer>();
HashMap<Integer, Set<Integer>> numLances = new HashMap<Integer, Set<Integer>>();
public void addLance(int valor) {
if(lances.get(valor) == null) {
lances.put(valor, 1);
addNumLance(1, valor);
} else {
int valorAntigo = lances.get(valor);
removeNumLance(valorAntigo, valor);
lances.put(valor, valorAntigo++);
addNumLance(valorAntigo++, valor);
}
}
private void addNumLance(int valor, int el) {
Set<Integer> valores = numLances.get(valor);
if(valores == null) {
valores = new HashSet<Integer>();
numLances.put(valor, valores);
}
valores.add(el);
}
private void removeNumLance(int valor, int el) {
Set<Integer> valores = numLances.get(valor);
if(valores != null) {
valores.remove(el);
}
}
public int getMenorLance() {
Set<Integer> conjunto = numLances.get(1);
int val = Collections.min(conjunto);
return val;
}
Você poderia ainda usar um SortedSet (TreeSet) no lugar de um hashset, pois isso já deixaria os lances ordenados. Isso evita o uso do Collections.min, que é muito mais custoso.
Me parece, como sugere uma parte do código que vc postou, que o seu aplicativo deve impedir a entrada de um lance já existente.
Isto simplificaria a solução do seu problema, pois é bem mais fácil obter o menor valor do que o menor e único.
E, só por curiosidade… não é o maior lance que ganha a parada?
Me parece, como sugere uma parte do código que vc postou, que o seu aplicativo deve impedir a entrada de um lance já existente.
Isto simplificaria a solução do seu problema, pois é bem mais fácil obter o menor valor do que o menor e único.
E, só por curiosidade… não é o maior lance que ganha a parada?
Acho que ele está tentando implementar aqueles leilões de tv, onde o menor lance único leva o produto.
Você poderia ainda usar um SortedSet (TreeSet) no lugar de um hashset, pois isso já deixaria os lances ordenados. Isso evita o uso do Collections.min, que é muito mais custoso.
Muito bem lembrado. Código reformulado:
HashMap<Integer, Integer> lances = new HashMap<Integer, Integer>();
SortedSet<Integer> lancesUnicos = new TreeSet<Integer>();
public void addLance(int valor) {
if(lances.get(valor) == null) {
lances.put(valor, 1);
lancesUnicos.add(valor);
} else {
int valorAntigo = lances.get(valor);
lances.put(valor, valorAntigo++);
lancesUnicos.remove(valor);
}
}
public int getMenorLance() {
return lancesUnicos.first();
}
Me parece, como sugere uma parte do código que vc postou, que o seu aplicativo deve impedir a entrada de um lance já existente.
Isto simplificaria a solução do seu problema, pois é bem mais fácil obter o menor valor do que o menor e único.
E, só por curiosidade… não é o maior lance que ganha a parada?
Acho que ele está tentando implementar aqueles leilões de tv, onde o menor lance único leva o produto.
Ok, faz sentido.
E neste caso realmente todo lance é bem-vindo.

Me parece, como sugere uma parte do código que vc postou, que o seu aplicativo deve impedir a entrada de um lance já existente. Isto simplificaria a solução do seu problema, pois é bem mais fácil obter o menor valor do que o menor e único. E, só por curiosidade... não é o maior lance que ganha a parada?
Ele poderia controlar na entrada através de 2 Sets. Um para lances não únicos já realizados, e outro para lances únicos.
Set<Integer> lancesNaoUnicos = new HashSet<Integer>();
SortedSet<Integer> lancesUnicos = new TreeSet<Integer>();
public void darLance(int valor) {
if (lancesNaoUnicos.contains(valor)) //Já foi dado
return;
if (lancesUnicos.remove(valor)) { //Se conseguiu remover dos lances únicos
lancesNaoUnicos.add(valor); //É pq é um lance duplicado.
} else {
lancesUnicos.add(valor); //Senão é um lance único.
}
}
public int menorLance() {
return lancesUnicos.first();
}
Uma classezinha para o lance que una o valor e a pessoa que deu o lance pode ser bastante útil nesse caso.
Concordo que para resolver o problema dois Sets são o suficiente, porém dessa maneira se perde informações que podem ser necessárias no futuro. Com dois Sets você sabe que o lance foi ofertado 1 vez ou mais de 1.
Digamos que ninguém dê um lance único e, consequentemente, não haja ganhador. Para evitar problemas, a organização resolve dividir o prêmio com quem deu o menor lance, sendo que ele não é mais único e pode ser divido por 2 pessoas ou mais. Teria que ser refeito parte do código já criado para atender os novos requisitos.
Concordo que para resolver o problema dois Sets são o suficiente, porém dessa maneira se perde informações que podem ser necessárias no futuro. Com dois Sets você sabe que o lance foi ofertado 1 vez ou mais de 1.Digamos que ninguém dê um lance único e, consequentemente, não haja ganhador. Para evitar problemas, a organização resolve dividir o prêmio com quem deu o menor lance, sendo que ele não é mais único e pode ser divido por 2 pessoas ou mais. Teria que ser refeito parte do código já criado para atender os novos requisitos.
Basta daí trocar o Set de lances não únicos por um List, mas haverá perda de performance.
Entretanto, também acho sua solução melhor. É como eu faria.
Correto isso mm .
Acho que ele está tentando implementar aqueles leilões de tv, onde o menor lance único leva o produto.
Bom sou novato em Java e a partir de suas ideia , apliquei da seguinte forma :Qq coisa corrigem-me plisss =]
Muito Obrigado !! :D
public class Carro implements Produto {
private String descricao;
Set<Lance> lancesNaoUnicos = new HashSet<Lance>();
SortedSet<Double> lancesUnicos = new TreeSet<Double>();
public Carro(String descricao) {
this.descricao = descricao;
}
//
@Override
public boolean Oferta(Lance lance) {
if(lancesNaoUnicos.contains(lance.getValor()) )
return false;
if(lancesUnicos.remove(lance.getValor())){
lancesNaoUnicos.add(lance);
}else{
lancesUnicos.add(lance.getValor());
}
return true;
}
//
@Override
public Lance finalizar() {
System.out.println("Lance Menor e Unico : "+lancesUnicos.first());
return null;
}
//
@Override
public String getDescricao() {
return descricao;
}
}