Nano Hash - криптовалюты, майнинг, программирование

объединить два списка в Java

У меня есть два списка с одинаковым количеством аргументов, и мне нужен элегантный способ их объединения (а не объединения).

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

    List<Double> list1 = ... // init here
    List<Double> list2 = ... // init here
    Function<Double, Double, Double> myFunc = ... // init here

    List<Double> ret = new ArrayList<Double>(size);

    for (int n = 0; n < size; ++n)
    {
        ret.add(func.apply(list1.get(n),
                           list2.get(n)));
    }
    return ret;

interface Function <X, Y, Z>
{
    Z apply(X arg1, Y arg2);
}

Есть ли некоторые существующие помощники, которые позволили бы мне сделать что-то вроде:

Lists.combine(list1, list2, myFunction);

Например, предположим, что у меня есть два списка целых чисел и функция f(x, y) = x * y).

Я хочу, чтобы полученный список был списком (x[i] * y[i])

Конкретно,

list1 = {1, 2, 3, 4}
list2 = {2, 3, 4, 4}

result = {2, 6, 12, 15}

Спасибо


  • Нет! Это просто застегивает их вместе, не трансформируя их. 04.10.2013
  • Скажем, у меня есть два списка целых чисел, я хочу, чтобы результирующий список был суммой двух элементов из каждого списка. 04.10.2013
  • Создание анонимного внутреннего класса Function требует более громоздкой работы, чем простое написание обычного цикла for, который вы бы получили без каких-либо причудливых функциональных приемов. На самом деле это трехстрочный цикл for, который не особенно сложен. 04.10.2013
  • Что делать, если то, что вы делаете с двумя списками, ОЧЕНЬ сложно или если вам приходится много заниматься прочесыванием в своих программах, но каждый раз комбинация выполняется по-разному? Вам нужен способ последовательно объединить два списка, не зная конкретных деталей того, что делать с каждым элементом, не так ли? 04.10.2013
  • @OneTwoThree: не имеет значения. Если это так сложно, вы выносите эту сложную логику в отдельную функцию, что эквивалентно тому, что вы в любом случае будете делать с вашим Function подходом. Вы по-прежнему повторяете меньше кода с помощью простого цикла for. 04.10.2013
  • @OneTwoThree проверьте мой ответ и метод Var-Args ... вы можете заменить ‹Double› вашим собственным общим типом, объявленным на уровне метода, например, private ‹T› T[] apply(int index, List‹ T›...lists){...}, что-то в этом роде 04.10.2013
  • 2, 6 12, 16? Вместо 15? 04.10.2013

Ответы:


1

Основная идея состоит в том, чтобы создать метод, который может одновременно извлекать все ваши индексы всех ваших списков и возвращать этот результат в виде массива или коллекции... вам не нужно их хранить, все, что вам нужно, это просто ссылка на их, и вы можете передать их в качестве параметров вашему методу

вот некоторые формы создания такого метода, и вы можете сделать общее значение, которое будет возвращено, если ваш поиск вернет неверный результат:

private List<Double> firstList = new ArrayList<Double>();
private List<Double> secondList = new ArrayList<Double>();
private List<Double> thirdList = new ArrayList<Double>();
private static final double OUT_OF_BOUNDS = -1;

// just to initialize the arrays
private void initializeLists() {
    // dont pay attention to this
    for (double d1 = 0, d2 = 500, d3 = 5000; d1 < 50; d1++, d2++, d3++) {
        firstList.add(d1);
        secondList.add(d2);
        thirdList.add(d3);
    }
}

// create a method to retrieve data from both lists, and return it in an array or even
// a new list
private double[] apply(int index) {
    if (index < firstList.size() && index < secondList.size()) {
        if (index >= 0) {
            return new double[] { firstList.get(index), secondList.get(index) };
        }
    }
    return new double[] { OUT_OF_BOUNDS, OUT_OF_BOUNDS };
}

// you can pass those lists as parameters
private double[] apply(int index, List<Double> firstList, List<Double> secondList) {
    if (index < firstList.size() && index < secondList.size()) {
        if (index >= 0) {
            return new double[] { firstList.get(index), secondList.get(index) };
        }
    }
    return new double[] { OUT_OF_BOUNDS, OUT_OF_BOUNDS };
}

// you can even pass undefined number of lists (var-args)and grab there values at onnce
private double[] apply(int index, List<Double>... lists) {

    int listsSize = lists.length;

    if (index >= 0) {

        double[] search = new double[listsSize];

        for (int listIndex = 0; listIndex < listsSize; listIndex++) {

            List<Double> currentList = lists[listIndex];

            if (index < currentList.size()) {
                search[listIndex] = currentList.get(index);

            } else {
                search[listIndex] = OUT_OF_BOUNDS;
            }

        }
        return search;
    }

    double[] invalidSearch = new double[listsSize];
    for (int i = 0; i < listsSize; i++) {
        invalidSearch[i] = OUT_OF_BOUNDS;
    }
    return invalidSearch;

}

// now the work

public void combineLists() {
    initializeLists();
    double[] search = null;

    // search for index Zero in both lists
    search = apply(0);
    System.out.println(Arrays.toString(search));
    // result : [0.0, 500.0]

    // search for index One in both list parameters
    search = apply(1, firstList, secondList);
    System.out.println(Arrays.toString(search));
    // result : [1.0, 501.0]

    // search for index Two in var-args list parameters
    search = apply(2, firstList, secondList, thirdList);
    System.out.println(Arrays.toString(search));
    // result : [2.0, 502.0, 5002.0]


    // search for wrong index
    search = apply(800);
    System.out.println(Arrays.toString(search));
    // result : [-1.0, -1.0]

    // search for wrong index
    search = apply(800, firstList, secondList);
    System.out.println(Arrays.toString(search));
    // result : [-1.0, -1.0]


    // search for wrong index
    search = apply(800, firstList, secondList, thirdList);
    System.out.println(Arrays.toString(search));
    // result : [-1.0, -1.0,-1.0]

}
03.10.2013
  • пример на двойниках, но вы можете заменить двойник универсальным типом, объявленным во время выполнения 04.10.2013

  • 2

    Вот одно решение. Проверка границ и вся обработка ошибок опущены:

    public class Reducer
    {
        public static <X, Y, Z> List<Z> reduce(List<X> list1, List<Y> list2, Function<X,Y,Z> func)
        {
            List<Z> result = new ArrayList<Z>();
            Iterator<X> i1 = list1.iterator();
            Iterator<Y> i2 = list2.iterator();
            for (int i=0; i<list1.size(); i++)
            {
                result.add(func.apply(i1.next(), i2.next()));
            }
            return result;
        }
    }
    
    public interface Function<X,Y,Z> {
        Z apply(X arg1, Y arg2);
    }
    

    И как это использовать

    public static void main(String[] args)
    {
        Function<Double, Double, Double> f = new Function<Double, Double, Double>() {
            @Override
            public Double apply(Double a1, Double a2) { return a1 * a2; }
        };
    
        List<Double> d1 = new ArrayList<Double>();
        List<Double> d2 = new ArrayList<Double>();
        List<Double> result = Reducer.reduce(d1, d2, f);
    }
    
    03.10.2013
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..