IT이야기

Java에서 2개의 목록에 가입하려면 어떻게 해야 하나요?

cyworld 2022. 6. 17. 21:48
반응형

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

반응형