Java에서 2개의 목록에 가입하려면 어떻게 해야 하나요?
상태: 원래 목록은 수정하지 마십시오.JDK만 있고 외부 라이브러리는 없습니다.원라이너 또는 JDK 1.3 버전의 보너스 포인트.
다음과 같은 간단한 방법이 있습니까?
List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);
Java 8의 경우:
List<String> newList = Stream.concat(listOne.stream(), listTwo.stream())
.collect(Collectors.toList());
즉석에서 한 줄 줄일 수 있습니다.
List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);
Apache Commons-Collections 라이브러리를 사용할 수 있습니다.
List<String> newList = ListUtils.union(list1, list2);
또 다른 Java 8 원라이너:
List<String> newList = Stream.of(listOne, listTwo)
.flatMap(Collection::stream)
.collect(Collectors.toList());
너로부터 후후 as as.Stream.of()
는 variadic입니다 연결할 수 있습니다.variadic 다 is다 。을 사용하다
List<String> newList = Stream.of(listOne, listTwo, listThree)
.flatMap(Collection::stream)
.collect(Collectors.toList());
요구 사항 중 하나는 원래 목록을 보존하는 것입니다. 을 사용하는 addAll()
목록 내 오브젝트에 대한 참조 수를 실질적으로 두 배로 늘릴 수 있습니다.리스트가 매우 클 경우 메모리 문제가 발생할 수 있습니다.
연결된 결과를 수정할 필요가 없는 경우 사용자 정의 목록 구현을 사용하여 이를 방지할 수 있습니다.커스텀 실장 클래스는 여러 행으로 구성되어 있습니다.분명히...사용하는 것은 짧고 달콤합니다.
Composite Unmodify List.java:
public class CompositeUnmodifiableList<E> extends AbstractList<E> {
private final List<? extends E> list1;
private final List<? extends E> list2;
public CompositeUnmodifiableList(List<? extends E> list1, List<? extends E> list2) {
this.list1 = list1;
this.list2 = list2;
}
@Override
public E get(int index) {
if (index < list1.size()) {
return list1.get(index);
}
return list2.get(index-list1.size());
}
@Override
public int size() {
return list1.size() + list2.size();
}
}
사용방법:
List<String> newList = new CompositeUnmodifiableList<String>(listOne,listTwo);
아마 단순하지는 않지만 흥미롭고 추악할 것이다.
List<String> newList = new ArrayList<String>() { { addAll(listOne); addAll(listTwo); } };
프로덕션 코드에 사용하지 마십시오.;)
단순하지 않지만 오버헤드를 조정하지 않음:
List<String> newList = new ArrayList<>(listOne.size() + listTwo.size());
newList.addAll(listOne);
newList.addAll(listTwo);
외부 라이브러리를 신경쓰지 않고 임의의 양의 목록을 연결하려고 이 질문을 발견했습니다.그래서 아마 다른 사람에게 도움이 될 것이다.
com.google.common.collect.Iterables#concat()
같은 로직을 1개의 다른 컬렉션에 적용하는 경우에 편리합니다.
8Java 8)
Stream.of
★★★★★★★★★★★★★★★★★」Stream.concat
)
제안된 솔루션은 세 가지 목록에 대한 것이지만 두 가지 목록에 적용할 수도 있습니다.Java 8에서는 Stream.of 또는 Stream.concat을 다음과 같이 사용할 수 있습니다.
List<String> result1 = Stream.concat(Stream.concat(list1.stream(),list2.stream()),list3.stream()).collect(Collectors.toList());
List<String> result2 = Stream.of(list1,list2,list3).flatMap(Collection::stream).collect(Collectors.toList());
Stream.concat
는 2개의 스트림을 입력으로 사용하여 느릿느릿 연결된 스트림을 만듭니다.이 스트림의 요소는 첫 번째 스트림의 모든 요소이고 두 번째 스트림의 모든 요소가 됩니다. 가지 에 이했습니다.Stream.concat
)의 2번입니다.
(varargs를 사용하여) 임의의 수의 목록을 가져와서 연결된 목록을 반환하는 메서드를 사용하여 다음과 같이 유틸리티 클래스를 작성할 수도 있습니다.
public static <T> List<T> concatenateLists(List<T>... collections) {
return Arrays.stream(collections).flatMap(Collection::stream).collect(Collectors.toList());
}
다음으로 이 방법을 다음과 같이 사용할 수 있습니다.
List<String> result3 = Utils.concatenateLists(list1,list2,list3);
다음으로 2행의 Java 8 솔루션을 나타냅니다.
List<Object> newList = new ArrayList<>();
Stream.of(list1, list2).forEach(newList::addAll);
다음 경우 이 방법을 사용하면 안 됩니다.
- 의
newList
수 없으며 되었을 수 . - 「」를
newList
병렬 스트림이며 에 대한 액세스입니다.newList
동기화되지 않았거나 스레드 세이프가 없습니다.
부작용에 대한 고려 때문에.
위의 두 가지 조건 모두 위의 두 가지 목록에 가입하는 경우에는 해당되지 않으므로 안전합니다.
다른 질문에 대한 이 답변을 바탕으로 합니다.
이것은 단순하고 한 줄에 불과하지만 listTwo의 내용을 listOne에 추가합니다.꼭 세 번째 목록에 내용을 넣어야 하나요?
Collections.addAll(listOne, listTwo.toArray());
조금 더 심플하게:
List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);
조금 짧게는 다음과 같습니다.
List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);
범용 Java 8 유틸리티 메서드를 생성하여 원하는 수의 목록을 만들 수 있습니다.
@SafeVarargs
public static <T> List<T> concat(List<T>... lists) {
return Stream.of(lists).flatMap(List::stream).collect(Collectors.toList());
}
대상 리스트가 선행되어 있는 경우는, oneliner 를 실행할 수 있습니다.
(newList = new ArrayList<String>(list1)).addAll(list2);
Java 8의 경우(다른 방법):
List<?> newList =
Stream.of(list1, list2).flatMap(List::stream).collect(Collectors.toList());
다른 하나의 라이너 솔루션 사용Java8
스트리밍, 이후flatMap
솔루션이 이미 게시되어 있습니다.다음은 이 솔루션이 없는 경우입니다.flatMap
List<E> li = lol.stream().collect(ArrayList::new, List::addAll, List::addAll);
또는
List<E> ints = Stream.of(list1, list2).collect(ArrayList::new, List::addAll, List::addAll);
코드
List<List<Integer>> lol = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
List<Integer> li = lol.stream().collect(ArrayList::new, List::addAll, List::addAll);
System.out.println(lol);
System.out.println(li);
산출량
[[1, 2, 3], [4, 5, 6]]
[1, 2, 3, 4, 5, 6]
java8을 사용하여 2개의 접근법으로 2개의 목록을 만들 수 있습니다.
List<String> list1 = Arrays.asList("S", "T");
List<String> list2 = Arrays.asList("U", "V");
1) 콘센트 사용:
List<String> collect2 = Stream.concat(list1.stream(), list2.stream()).collect(toList());
System.out.println("collect2 = " + collect2); // collect2 = [S, T, U, V]
2) platMap 사용:
List<String> collect3 = Stream.of(list1, list2).flatMap(Collection::stream).collect(toList());
System.out.println("collect3 = " + collect3); // collect3 = [S, T, U, V]
내 생각에 가장 똑똑한 것 같아:
/**
* @param smallLists
* @return one big list containing all elements of the small ones, in the same order.
*/
public static <E> List<E> concatenate (final List<E> ... smallLists)
{
final ArrayList<E> bigList = new ArrayList<E>();
for (final List<E> list: smallLists)
{
bigList.addAll(list);
}
return bigList;
}
대부분의 답변에서 Array List를 사용할 것을 제안합니다.
List<String> newList = new LinkedList<>(listOne);
newList.addAll(listTwo);
효율적인 추가 작업을 위해 LinkedList를 사용하는 것을 선호합니다.
Array List 추가는 O(1) 상각되지만 어레이 크기를 조정하고 복사해야 하므로 O(n) 최악의 경우입니다.Linked List 추가는 항상 상수 O(1)입니다.
자세한 내용은 https://stackoverflow.com/a/322742/311420 를 참조해 주세요.
스태틱 Import 및 도우미 클래스로 실행할 수 있습니다.
nb 이 클래스의 생성은 아마 개선될 것이다.
public class Lists {
private Lists() { } // can't be instantiated
public static List<T> join(List<T>... lists) {
List<T> result = new ArrayList<T>();
for(List<T> list : lists) {
result.addAll(list);
}
return results;
}
}
그러면 이렇게 할 수 있어요.
import static Lists.join;
List<T> result = join(list1, list2, list3, list4);
Java 8 버전(개체 키에 의한 가입 지원):
public List<SomeClass> mergeLists(final List<SomeClass> left, final List<SomeClass> right, String primaryKey) {
final Map<Object, SomeClass> mergedList = new LinkedHashMap<>();
Stream.concat(left.stream(), right.stream())
.map(someObject -> new Pair<Object, SomeClass>(someObject.getSomeKey(), someObject))
.forEach(pair-> mergedList.put(pair.getKey(), pair.getValue()));
return new ArrayList<>(mergedList.values());
}
public static <T> List<T> merge(List<T>... args) {
final List<T> result = new ArrayList<>();
for (List<T> list : args) {
result.addAll(list);
}
return result;
}
도우미 클래스를 사용합니다.
제안:
public static <E> Collection<E> addAll(Collection<E> dest, Collection<? extends E>... src) {
for(Collection<? extends E> c : src) {
dest.addAll(c);
}
return dest;
}
public static void main(String[] args) {
System.out.println(addAll(new ArrayList<Object>(), Arrays.asList(1,2,3), Arrays.asList("a", "b", "c")));
// does not compile
// System.out.println(addAll(new ArrayList<Integer>(), Arrays.asList(1,2,3), Arrays.asList("a", "b", "c")));
System.out.println(addAll(new ArrayList<Integer>(), Arrays.asList(1,2,3), Arrays.asList(4, 5, 6)));
}
public static <T> List<T> merge(@Nonnull final List<T>... list) {
// calculate length first
int mergedLength = 0;
for (List<T> ts : list) {
mergedLength += ts.size();
}
final List<T> mergedList = new ArrayList<>(mergedLength);
for (List<T> ts : list) {
mergedList.addAll(ts);
}
return mergedList;
}
내가 가장 좋아하는 방법은 fluent api와 Guava를 사용하는 것이다.
List<String> combined = ImmutableList.<String>builder().addAll(list1).addAll(list2).build()
간단하다고 하는 것은 아니지만, 1인용 보너스를 말씀하셨습니다.-)
Collection mergedList = Collections.list(new sun.misc.CompoundEnumeration(new Enumeration[] {
new Vector(list1).elements(),
new Vector(list2).elements(),
...
}))
원라이너 근처는 아니지만 이것이 가장 간단한 방법이라고 생각합니다.
List<String> newList = new ArrayList<String>(l1);
newList.addAll(l2);
for(String w:newList)
System.out.printf("%s ", w);
다음은 스트림과 Java 8을 사용한 접근법입니다.목록의 유형이 다르고 그것들을 다른 유형의 목록으로 결합하고 싶은 경우입니다.
public static void main(String[] args) {
List<String> list2 = new ArrayList<>();
List<Pair<Integer, String>> list1 = new ArrayList<>();
list2.add("asd");
list2.add("asdaf");
list1.add(new Pair<>(1, "werwe"));
list1.add(new Pair<>(2, "tyutyu"));
Stream stream = Stream.concat(list1.stream(), list2.stream());
List<Pair<Integer, String>> res = (List<Pair<Integer, String>>) stream
.map(item -> {
if (item instanceof String) {
return new Pair<>(0, item);
}
else {
return new Pair<>(((Pair<Integer, String>)item).getKey(), ((Pair<Integer, String>)item).getValue());
}
})
.collect(Collectors.toList());
}
이것을 정적으로 실시하려면 , 다음의 순서를 실행할 수 있습니다.
예제에서는 자연 순서(==Enum-order)에서 2개의 EnumSet을 사용합니다.A, B
그 다음에 가입합니다.ALL
목록.
public static final EnumSet<MyType> CATEGORY_A = EnumSet.of(A_1, A_2);
public static final EnumSet<MyType> CATEGORY_B = EnumSet.of(B_1, B_2, B_3);
public static final List<MyType> ALL =
Collections.unmodifiableList(
new ArrayList<MyType>(CATEGORY_A.size() + CATEGORY_B.size())
{{
addAll(CATEGORY_A);
addAll(CATEGORY_B);
}}
);
언급URL : https://stackoverflow.com/questions/189559/how-do-i-join-two-lists-in-java
'IT이야기' 카테고리의 다른 글
프록시를 사용하여 vue CLI 개발 서버에서 리다이렉트를 처리하려면 어떻게 해야 합니까? (0) | 2022.06.17 |
---|---|
Vue.js 'v-bind:class'가 업데이트되지만 업데이트되지 않음 (0) | 2022.06.17 |
Vuejs SPA의 프론트 엔드를 보호하려면 어떻게 해야 합니까? (0) | 2022.06.16 |
Java에서 가장 자주 발생하는 동시성 문제는 무엇입니까? (0) | 2022.06.16 |
Vue.js에게 소품을 넘겨주는 거? (0) | 2022.06.16 |