Как закрепить два списка Java
У меня есть 2 списка:
List<String> subjectArr = Arrays.asList<String>("aa", "bb", "cc");
List<Long> numArr = Arrays.asList<Long>(2L, 6L, 4L);
Как мне создать новый List
и закрепить в нем два списка?
List<?> subjectNumArr = zip(subjectArr, numArr);
// subjectNumArr == [{'aa',2},{'bb',6},{'cc',4}]
Ответы
Ответ 1
Здесь решение Java-8 с использованием класса Pair
(как в ответе @ZhekaKozlov):
public static <A, B> List<Pair<A, B>> zipJava8(List<A> as, List<B> bs) {
return IntStream.range(0, Math.min(as.size(), bs.size()))
.mapToObj(i -> new Pair<>(as.get(i), bs.get(i)))
.collect(Collectors.toList());
}
Ответ 2
Используйте ArrayList Map.Entry<String, Long>
, проверяя, что оба arraylists имеют одинаковый размер (как вам кажется, ваше требование), например:
List<Map.Entry<String,Long>> subjectNumArr = new ArrayList<>(numArr.size());
if (subjectArr.size() == numArr.size()) {
for (int i = 0; i < subjectArr.size(); ++i) {
subjectNumArr.add(new AbstractMap.SimpleEntry<String, Long>(subjectArr.get(i), numArr.get(i));
}
}
Чтобы весь код вам нужен!
Затем, чтобы перебрать результаты, используйте что-то вроде:
for (Map.Entry<String, Long> entry : subjectNumArr) {
String key = entry.getKey();
Long value = entry.getValue();
}
или, вы можете просто получить пару в позиции я (сохраняя порядок вставки), используя:
Map.Entry<String, Long> entry = subjectNumArr.get(i);
Это также может содержать повторяющиеся записи, в отличие от предлагаемого мной решения карты, не требуя определения вашего собственного класса (пары).
Ответ 3
Операция, которую вы хотите, называется zipping.
Сначала вам нужна структура данных, которая содержит два объекта. Назовем его Pair
:
public final class Pair<A, B> {
private final A left;
private final B right;
public Pair(A left, B right) {
this.left = left;
this.right = right;
}
public A left() { return left; }
public B right() { return right; }
public String toString() {
return "{" + left + "," + right + "}";
}
}
Затем вам нужно реализовать метод zip
:
public static <A, B> List<Pair<A, B>> zip(List<A> as, List<B> bs) {
Iterator<A> it1 = as.iterator();
Iterator<B> it2 = bs.iterator();
List<Pair<A, B>> result = new ArrayList<>();
while (it1.hasNext() && it2.hasNext()) {
result.add(new Pair<A, B>(it1.next(), it2.next()));
}
return result;
}
И, наконец, использование zip
:
zip(subjectArr, numArr);
Ответ 4
В соответствии с связанным вопросом вы можете использовать Guava ( >= 21.0) для этого:
List<String> subjectArr = Arrays.asList("aa", "bb", "cc");
List<Long> numArr = Arrays.asList(2L, 6L, 4L);
List<Pair> pairs = Streams.zip(subjectArr.stream(), numArr.stream(), Pair::new)
.collect(Collectors.toList());
Ответ 5
Я согласен с vefthym, однако, если вам нужно сделать с помощью списка, тогда создайте класс, как показано ниже:
class DirtyCoding{
String subject;
int numbr;
}
Затем перейдите по списку, создайте объект DirtyCoding
, заполните его и добавьте, затем добавьте его в List<DirtyCoding>
.
Ответ 6
Используйте один из ответов потоков Zipping с помощью JDK8 с lambda (java.util.stream.Streams.zip)
для zip и применения функции в то же время
например. Использование сжатого потока:
<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));
});
}
для которого вы также можете использовать Guava Streams.zip()
Ответ 7
Вы должны создать ArrayList of List:
ArrayList<List> subjectNumArr = new ArrayList<>();
Iterator iter = subjectArr.iterator();
int count=0;
while(iter.hasNext()){
subjectNumArr.add(Arrays.asList(iter.next(),numArr.get[count++]);
}
Ответ 8
Мои идеи:
- Определите класс для ваших пар. Это делает ваш код расширяемым (т.е. Если вы хотите добавить третье поле).
- Определите свои списки с помощью удобного метода
Arrays.asList
. Это легко понять, коротко и автоматически генерирует общие коллекции.
- Используйте суперклассы или интерфейсы как переменные типы. Я использовал
List
в примере, возможно, Collection
будет еще лучше. Только объявляйте переменные как ArrayList
, если вам нужен такой список. Это даст вам возможность использовать другие реализации без необходимости менять код.
Я бы создал объекты Pair
следующим образом:
import java.util.*;
class Pair {
String subject;
Long num;
}
public class Snippet {
public static void main(String[] args) {
List<String> subjectArr = Arrays.asList("aa", "bb", "cc");
List<Long> numArr = Arrays.asList(2l,6l,4l);
// create result list
List<Pair> pairs = new ArrayList<>();
// determine result size
int length = Math.min(subjectArr.size(), numArr.size());
// create pairs
for (int position = 0; position < length; position++) {
Pair pair = new Pair();
pair.subject = subjectArr.get(position);
pair.num = numArr.get(position);
pairs.add(pair);
}
}
}
Ответ 9
Чтобы получить Iterator<C>
из Iterator<A>
, Iterator<B>
и BiFunction<A, B, C>
:
public static <A, B, C> Iterator<C> map(Iterator<A> a, Iterator<B> b, BiFunction<A, B, C> f) {
return new Iterator<C>() {
public boolean hasNext() {
return a.hasNext() && b.hasNext(); // This uses the shorter of the two 'Iterator's.
}
public C next() {
return f.apply(a.next(), b.next());
}
};
}
Ответ 10
В Java 8:
Вы можете сделать это в одной строке, используя класс Stream и Collectors.
В Java 7/6/5:
List list = new ArrayList();
if(subjectArr.size() == numArr.size())
{
for (int i = 0; i < subjectArr.size(); i++) { // Loop through every subject/name
list.add(subjectArr.get(i) + " " + numArr.get(i)); // Concat the two, and add it
}
}