В Java 8 есть способ сопоставить функцию над двумя потоками? [Дубликат]

  1. Сначала вы входите в свою учетную запись heroku
  2. . Затем вы переходите к разделу базы данных 3. Там вы создаете базу данных, нажимая на Create Database
  3. . Затем создается ваша база данных heroku и вы можете увидеть его данные, такие как
  4. host = ...

    database = ...

    Пользователь = ...

    Порт = ...

    Пароль = ...

    Теперь подключитесь к базе данных с помощью интерактивного клиентского терминала PostgreSQL.

    Если вы у вас его уже нет, вам придется обратиться к пакету управления пакетами вашей платформы (например, на Ubuntu запустить sudo apt-get install postgresql-client) или перейти на postgresql.org, где вы найдете доступный для загрузки - встроенные бинарные пакеты, подходящие для FreeBSD, Linux, Mac, Solaris и Windows, а также другие варианты установки.

    To connect, call psql with the -h option to specify the server’s hostname, -U to specify     the username, and then the database name:
    
    root@yogesh-System-model:~# psql -h [**Host Name**] -U [**User Name**] [**database Name**]
        Password for user hdwvhbehqlishy: ********
        psql (8.4.9, server 9.0.5)
        WARNING: psql version 8.4, server version 9.0.
         Some psql features might not work.
        SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
        Type "help" for help.
    
    
    df7r55a12o64m4==> CREATE TABLE [Table_name](your_id SERIAL, Name text, Address text);
    

    Это создаст таблицу ....

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

    Если какие-либо проблемы могут ссылаться на этот учебник

    Это один из способов ..... другой способ будет использовать Jack DB в котором вы сможете запускать любые запросы и просматривать данные в своей БД, расположенной в Heroku.

116
задан Holger 25 January 2016 в 19:36
поделиться

13 ответов

Мне тоже это нужно, поэтому я просто взял исходный код из b93 и поместил его в класс «util». Мне пришлось немного изменить его, чтобы работать с текущим API.

Для справки здесь приведен рабочий код (возьмите его на свой страх и риск ...):

public static<A, B, C> Stream<C> zip(Stream<? extends A> a,
                                     Stream<? extends B> b,
                                     BiFunction<? super A, ? super B, ? extends C> zipper) {
    Objects.requireNonNull(zipper);
    Spliterator<? extends A> aSpliterator = Objects.requireNonNull(a).spliterator();
    Spliterator<? extends B> bSpliterator = Objects.requireNonNull(b).spliterator();

    // Zipping looses DISTINCT and SORTED characteristics
    int characteristics = aSpliterator.characteristics() & bSpliterator.characteristics() &
            ~(Spliterator.DISTINCT | Spliterator.SORTED);

    long zipSize = ((characteristics & Spliterator.SIZED) != 0)
            ? Math.min(aSpliterator.getExactSizeIfKnown(), bSpliterator.getExactSizeIfKnown())
            : -1;

    Iterator<A> aIterator = Spliterators.iterator(aSpliterator);
    Iterator<B> bIterator = Spliterators.iterator(bSpliterator);
    Iterator<C> cIterator = new Iterator<C>() {
        @Override
        public boolean hasNext() {
            return aIterator.hasNext() && bIterator.hasNext();
        }

        @Override
        public C next() {
            return zipper.apply(aIterator.next(), bIterator.next());
        }
    };

    Spliterator<C> split = Spliterators.spliterator(cIterator, zipSize, characteristics);
    return (a.isParallel() || b.isParallel())
           ? StreamSupport.stream(split, true)
           : StreamSupport.stream(split, false);
}
61
ответ дан jubobs 22 August 2018 в 06:57
поделиться
  • 1
    Не должен ли результирующий поток быть SIZED, если поток равен SIZED, а не оба? – Didier L 28 June 2015 в 10:49
  • 2
    Я так не думаю. Для этой реализации оба потока должны быть SIZED. Это зависит от того, как вы определяете zipping. Например, если вы можете закрепить два потока, которые имеют разный размер? Каким будет тогда получившийся поток? Я считаю, что именно поэтому эта функция фактически была исключена из API. Есть много способов сделать это, и пользователь должен решить, какое поведение должно быть «правильным». один. Не могли бы вы отбросить элементы из более длинного потока или заполнить более короткий список? Если да, с какими значениями? – siki 29 June 2015 в 14:47
  • 3
    Если я что-то не хватает, нет необходимости в каком-либо литье (например, Spliterator<A>). – jubobs 11 August 2016 в 14:41
  • 4
    Есть ли сайт, на котором размещен исходный код Java 8 b93? У меня проблемы с поиском. – Starwarswii 7 July 2017 в 18:08

Если кому это еще нужно, в библиотеке streamex есть функция StreamEx.zipWith:

StreamEx<String> givenNames = StreamEx.of("Leo", "Fyodor")
StreamEx<String> familyNames = StreamEx.of("Tolstoy", "Dostoevsky")
StreamEx<String> fullNames = givenNames.zipWith(familyNames, (gn, fn) -> gn + " " + fn);

fullNames.forEach(System.out::println);  // prints: "Leo Tolstoy\nFyodor Dostoevsky\n"
0
ответ дан const.grigoryev 22 August 2018 в 06:57
поделиться

Я смиренно предлагаю эту реализацию. Полученный поток усекается до более короткого из двух входных потоков.

public static <L, R, T> Stream<T> zip(Stream<L> leftStream, Stream<R> rightStream, BiFunction<L, R, T> combiner) {
    Spliterator<L> lefts = leftStream.spliterator();
    Spliterator<R> rights = rightStream.spliterator();
    return StreamSupport.stream(new AbstractSpliterator<T>(Long.min(lefts.estimateSize(), rights.estimateSize()), lefts.characteristics() & rights.characteristics()) {
        @Override
        public boolean tryAdvance(Consumer<? super T> action) {
            return lefts.tryAdvance(left->rights.tryAdvance(right->action.accept(combiner.apply(left, right))));
        }
    }, leftStream.isParallel() || rightStream.isParallel());
}
0
ответ дан Doradus 22 August 2018 в 06:57
поделиться

Это здорово. Я должен был закрепить два потока на карте с одним потоком, являющимся ключом, а другой - значением

Stream<String> streamA = Stream.of("A", "B", "C");
Stream<String> streamB  = Stream.of("Apple", "Banana", "Carrot", "Doughnut");    
final Stream<Map.Entry<String, String>> s = StreamUtils.zip(streamA,
                    streamB,
                    (a, b) -> {
                        final Map.Entry<String, String> entry = new AbstractMap.SimpleEntry<String, String>(a, b);
                        return entry;
                    });

System.out.println(s.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())));

Вывод: {A = Apple, B = Banana, C = Carrot}

0
ответ дан Gnana 22 August 2018 в 06:57
поделиться

Методы упомянутого вами класса были перемещены в интерфейс Stream в пользу методов по умолчанию. Но кажется, что метод zip удален. Возможно, потому что неясно, каково поведение по умолчанию для потоков разного размера. Но реализация желаемого поведения прямолинейна:

static <T> boolean every(
  Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred) {
    Iterator<T> it=c2.iterator();
    return c1.stream().allMatch(x->!it.hasNext()||pred.test(x, it.next()));
}
static <T> T find(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred) {
    Iterator<T> it=c2.iterator();
    return c1.stream().filter(x->it.hasNext()&&pred.test(x, it.next()))
      .findFirst().orElse(null);
}
9
ответ дан Holger 22 August 2018 в 06:57
поделиться
  • 1
    Разве не predicate вы передали фильтр stateful ? Это нарушает контракт по методу и особенно не работает при параллельной обработке потока. – Andreas 17 August 2015 в 09:25
  • 2
    @Andreas: ни одно из решений здесь не поддерживает параллельную обработку. Поскольку мои методы не возвращают поток, они обеспечивают, чтобы потоки не выполнялись параллельно. Аналогично, код принятого ответа возвращает поток, который можно преобразовать в параллель, но фактически не будет делать ничего параллельно. Тем не менее, государственные предикаты не поощряются, но не нарушают контракт. Они могут использоваться даже в параллельном контексте, если вы убедитесь, что обновление состояния является потокобезопасным. В некоторых ситуациях они неизбежны, например. превращение потока в отдельный - это предикат состояния per se . – Holger 17 August 2015 в 09:47
  • 3
    @Andreas: вы можете догадаться, почему эти операции были удалены из Java API ... – Holger 17 August 2015 в 09:48

AOL cyclops-react , в который я вношу свой вклад, также обеспечивает функцию zipping, как через реализацию расширенного потока , так и реализует интерфейс реактивных потоков ReactiveSeq и через StreamUtils, который предлагает многие из тех же функций с помощью статических методов для стандартных потоков Java.

 List<Tuple2<Integer,Integer>> list =  ReactiveSeq.of(1,2,3,4,5,6)
                                                  .zip(Stream.of(100,200,300,400));


  List<Tuple2<Integer,Integer>> list = StreamUtils.zip(Stream.of(1,2,3,4,5,6),
                                                  Stream.of(100,200,300,400));

Он также предлагает более обобщенную аппликативную основанную на zipping. Например.

   ReactiveSeq.of("a","b","c")
              .ap3(this::concat)
              .ap(of("1","2","3"))
              .ap(of(".","?","!"))
              .toList();

   //List("a1.","b2?","c3!");

   private String concat(String a, String b, String c){
    return a+b+c;
   }

И даже возможность соединять каждый элемент в одном потоке с каждым элементом в другом

   ReactiveSeq.of("a","b","c")
              .forEach2(str->Stream.of(str+"!","2"), a->b->a+"_"+b);

   //ReactiveSeq("a_a!","a_2","b_b!","b_2","c_c!","c2")
1
ответ дан John McClean 22 August 2018 в 06:57
поделиться

Переключение двух потоков с использованием JDK8 с помощью лямбда ( gist ).

public static <A, B, C> Stream<C> zip(Stream<A> streamA, Stream<B> streamB, BiFunction<A, B, C> zipper) {
    final Iterator<A> iteratorA = streamA.iterator();
    final Iterator<B> iteratorB = streamB.iterator();
    final Iterator<C> iteratorC = new Iterator<C>() {
        @Override
        public boolean hasNext() {
            return iteratorA.hasNext() && iteratorB.hasNext();
        }

        @Override
        public C next() {
            return zipper.apply(iteratorA.next(), iteratorB.next());
        }
    };
    final boolean parallel = streamA.isParallel() || streamB.isParallel();
    return iteratorToFiniteStream(iteratorC, parallel);
}

public static <T> Stream<T> iteratorToFiniteStream(Iterator<T> iterator, boolean parallel) {
    final Iterable<T> iterable = () -> iterator;
    return StreamSupport.stream(iterable.spliterator(), parallel);
}
20
ответ дан Karol Król 22 August 2018 в 06:57
поделиться
  • 1
    Хорошее решение и (относительно) компактный! Требуется, чтобы вы положили import java.util.function.*; и import java.util.stream.*; в начало файла. – sffc 13 September 2015 в 08:17
  • 2
    Обратите внимание, что это операция терминала в потоке. Это означает, что для бесконечных потоков этот метод ломается – smac89 26 October 2017 в 17:47

Если у вас есть Guava в вашем проекте, вы можете использовать метод Streams.zip (был добавлен в Guava 21):

Возвращает поток, в котором каждый элемент является результатом передачи соответствующему элементу каждого из streamA и streamB в функцию. Результирующий поток будет только до тех пор, пока более короткий из двух входных потоков; если один поток длиннее, его дополнительные элементы будут проигнорированы. Полученный поток неэффективно расщепляется. Это может повредить параллельной работе.

 public class Streams {
     ...

     public static <A, B, R> Stream<R> zip(Stream<A> streamA,
             Stream<B> streamB, BiFunction<? super A, ? super B, R> function) {
         ...
     }
 }
22
ответ дан lbalazscs 22 August 2018 в 06:57
поделиться

Библиотека Lazy-Seq предоставляет функции zip.

https://github.com/nurkiewicz/LazySeq

Эта библиотека сильно вдохновлена scala.collection.immutable.Stream и направлена ​​на обеспечение неизменной, поточно-безопасной и простой в использовании ленивой реализации последовательности, возможно бесконечной.

6
ответ дан Nick Siderakis 22 August 2018 в 06:57
поделиться

Поскольку я не могу представить себе использование zipping для коллекций, отличных от индексированных (списки), и я большой поклонник простоты, это было бы моим решением:

<A,B,C>  Stream<C> zipped(List<A> lista, List<B> listb, BiFunction<A,B,C> zipper){
     int shortestLength = Math.min(lista.size(),listb.size());
     return IntStream.range(0,shortestLength).mapToObject( i -> {
          return zipper.apply(lista.get(i), listb.get(i));
     });        
}
10
ответ дан Rafael 22 August 2018 в 06:57
поделиться
public class Tuple<S,T> {
    private final S object1;
    private final T object2;

    public Tuple(S object1, T object2) {
        this.object1 = object1;
        this.object2 = object2;
    }

    public S getObject1() {
        return object1;
    }

    public T getObject2() {
        return object2;
    }
}


public class StreamUtils {

    private StreamUtils() {
    }

    public static <T> Stream<Tuple<Integer,T>> zipWithIndex(Stream<T> stream) {
        Stream<Integer> integerStream = IntStream.range(0, Integer.MAX_VALUE).boxed();
        Iterator<Integer> integerIterator = integerStream.iterator();
        return stream.map(x -> new Tuple<>(integerIterator.next(), x));
    }
}
1
ответ дан robby_pelssers 22 August 2018 в 06:57
поделиться

zip - одна из функций, предоставляемых библиотекой protonpack .

Stream<String> streamA = Stream.of("A", "B", "C");
Stream<String> streamB  = Stream.of("Apple", "Banana", "Carrot", "Doughnut");

List<String> zipped = StreamUtils.zip(streamA,
                                      streamB,
                                      (a, b) -> a + " is for " + b)
                                 .collect(Collectors.toList());

assertThat(zipped,
           contains("A is for Apple", "B is for Banana", "C is for Carrot"));
38
ответ дан Samir Talwar 22 August 2018 в 06:57
поделиться
0
ответ дан Dan Borza 5 November 2018 в 04:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: