Как создать ошибку, если число появляется в списке более одного раза - PullRequest
1 голос
/ 20 января 2020

У меня есть список [0, 0, 1, 0, 1, 2, 0, 2, 3], и я хочу найти способ вызвать ошибку, если число повторяется в списке.

Итак, я знаю, что Collections.frequency может подсчитать, сколько раз число найдено в списке.

if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(0)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(0) + " apparaît plus d'une fois sur la ligne 1");
if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(1)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(1) + " apparaît plus d'une fois sur la ligne 1");
if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(2)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(2) + " apparaît plus d'une fois sur la ligne 1");
if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(3)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(3) + " apparaît plus d'une fois sur la ligne 1");
if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(4)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(4) + " apparaît plus d'une fois sur la ligne 1");
if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(5)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(5) + " apparaît plus d'une fois sur la ligne 1");
if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(6)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(6) + " apparaît plus d'une fois sur la ligne 1");
if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(7)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(7) + " apparaît plus d'une fois sur la ligne 1");
if (Collections.frequency((Collection<?>) smallerLists.toArray()[0], ((ArrayList<Integer>) smallerLists.toArray()[0]).get(8)) > 1) ;
System.out.println("ERREUR : Le nombre " + ((ArrayList<Integer>) smallerLists.toArray()[0]).get(8) + " apparaît plus d'une fois sur la ligne 1");

Я знаю, что этот код тяжелый, и я уверен, что есть более простой способ сделать это (возможно, итерация? Я все еще очень новичок в программировании). Проще всего было бы создать исключение, создав конструктор, но я застрял ... Спасибо!

Ответы [ 3 ]

1 голос
/ 21 января 2020

Я бы сказал, использовать Collectors.groupingBy с Collectors.counting(), чтобы собрать значение со счетом в Map

Map<String, Long> valueWithCount = list.stream()
        .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));

А затем передать Map, чтобы найти любое значение с числом больше 1

boolean result = valueWithCount.entrySet()
                               .stream()
                               .anyMatch(i->i.getKey().equals(10) && i.getValue()>1);

Вы можете объединить оба в одну операцию

boolean result = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet().stream().anyMatch(i -> i.getKey().equals(10) && i.getValue() > 1);
0 голосов
/ 21 января 2020

Вместо того чтобы генерировать исключение, вы можете обрабатывать ошибки с помощью обратного вызова. Таким образом, вы можете иметь дело с несколькими исключениями в списке. В приведенном ниже решении используется новый класс с поддерживающим TreeMap и обратным вызовом для обработки дубликатов либо в исходном массиве, переданном в конструктор, либо для дополнительных элементов, добавленных с помощью метода addItem.

Код выдает следующий вывод:

Constructor: 
We have a dupe: 0 which has occurred 2 times so far
We have a dupe: 0 which has occurred 3 times so far
We have a dupe: 1 which has occurred 2 times so far
We have a dupe: 0 which has occurred 4 times so far
We have a dupe: 2 which has occurred 2 times so far

Add new items: 
Duplicate 4 has had 2 occurrences

Frequency List
    0 appears 4 times
    1 appears 2 times
    2 appears 2 times
    3 appears 1 times
    4 appears 2 times

Обратите внимание, что addItem и конструктор перегружены для обработки нулевого обратного вызова и что второй вызов addItem передает выражение Lambda в качестве обратного вызова. .

import java.util.Set;
import java.util.TreeMap;

interface DupeHandler{
    public void handleDupe(Integer dupValue, Integer dupCount);
}

class FrequencyList {
    private TreeMap<Integer, Integer> _tm = new TreeMap<Integer, Integer>();

    public FrequencyList(int[] array){
        this(array, (DupeHandler)null);
    }

    public FrequencyList(int[] array, DupeHandler m){
        for(var i : array){
            addItem(i,m);
        }
    }

    public void addItem(Integer i){
        addItem(i, null);
    }

    public void addItem(Integer key, DupeHandler m){
        Integer count = _tm.get(key);
        if(count==null){
            _tm.put(key, Integer.valueOf(1));
        } else {
            Integer newCount = (Integer.valueOf(count+1));
            _tm.put(key, newCount);
            if(m!=null){
                m.handleDupe(key, newCount);
            }
        }
    }

    public Set<Integer> getUniqueValues(){
        return _tm.keySet();
    }

    @Override
    public String toString() {
        StringBuilder sb=new StringBuilder();
        sb.append("\nFrequency List\n");
        for(var k:_tm.keySet()){
            sb.append("\t" + k.toString() + " appears " + _tm.get(k).toString()+ " times\n");
        }
        return sb.toString();
    }
}

public class FrequencyListTest implements DupeHandler{
    public static void main(String[] args) {
        int[] intArray = new int[] {0,0,1,0,1,2,0,2,3};
        FrequencyListTest flt = new FrequencyListTest();

        System.out.println("Constructor: ");
        FrequencyList fl = new FrequencyList(intArray, flt);

        System.out.println("\nAdd new items: ");
        fl.addItem(4,flt);
        // callback can also be passed in as a lambda expression
        fl.addItem(4,(n,c)-> 
            System.out.println("Duplicate " + n + " has had " + c + " occurrences"));

        System.out.println(fl);

    }

    @Override
    public void handleDupe(Integer dupValue, Integer dupCount) {
        System.out.println("We have a dupe: " + dupValue + " which has occurred " + dupCount + " times so far");
    }
}

0 голосов
/ 21 января 2020

Вы можете найти дубликаты, используя одно из решений, предложенных в уже заданных вопросах, таких как Идентифицировать дубликаты в списке .

Затем, если найден дубликат, вы можете передать приведите к вашему конструктору исключений, где вы создаете свое сообщение. Тогда брось свое исключение.

...