Java 비교 두 목록


92

두 개의 목록이 있습니다 (Java 목록이 아니라 두 개의 열이라고 말할 수 있습니다)

예를 들면

**List 1**            **Lists 2**
  milan                 hafil
  dingo                 iga
  iga                   dingo
  elpha                 binga
  hafil                 mike
  meat                  dingo
  milan
  elpha
  meat
  iga                   
  neeta.peeta    

동일한 요소 수를 반환하는 메서드를 원합니다. 이 예에서는 3이어야하며 목록과 다른 값의 유사한 값도 반환해야합니다.

그렇다면 해시 맵을 사용해야한다면 어떤 방법으로 결과를 얻을 수 있습니까?

도와주세요

추신 : 학교 과제가 아니에요 :) 그러니 그냥 안내 해주시면


목록이 Java 목록, 해시 맵 또는 데이터 구조가 아닌 데이터 구조를 제안하십시오
user238384

1
예외적 인 경우에해야 할 일에 대해 생각하십시오. 목록에 동일한 값이 두 번 포함될 수 있습니까? 만약 그렇다면, "dingo"가 두 목록에 두 번 있으면 공통된 두 요소로 계산됩니까 아니면 하나만 계산됩니까?
JavadocMD

목록 중 하나를 수정할 수 있습니까?
Anthony Forloney 2010 년

편집하는 방법 ?? 예 각 목록에는 유사한 값이 여러 번 포함될 수 있습니다.
user238384

질문 바로 뒤에 태그 아래에 작은 수정 링크 가 있어야 합니다.
OscarRyz

답변:


159

편집하다

다음은 두 가지 버전입니다. 하나 사용 ArrayList하고 다른 사용HashSet

필요한 것을 얻을 때까지 비교하고 여기 에서 자신의 버전을 만드십시오 .

이것은 다음을 포함하기에 충분해야합니다.

추신 : 학교 과제가 아니에요 :) 그러니 그냥 안내 해주시면

질문의 일부입니다.

원래 답변 계속 :

java.util.Collection 및 / 또는이를 java.util.ArrayList위해 사용할 수 있습니다 .

나 retainAll의 방법은 다음을 수행합니다

지정된 컬렉션에 포함 된이 컬렉션의 요소 만 유지합니다.

이 샘플을 참조하십시오.

import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;

public class Repeated {
    public static void main( String  [] args ) {
        Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
        Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));

        listOne.retainAll( listTwo );
        System.out.println( listOne );
    }
}

편집하다

두 번째 부분 (유사한 값)의 경우 removeAll 메소드를 사용할 수 있습니다 .

지정된 컬렉션에도 포함 된이 컬렉션의 모든 요소를 ​​제거합니다.

이 두 번째 버전은 유사한 값과 반복되는 핸들을 제공합니다 (삭제하여).

이번에는 Collectiona Set대신에 될 수 있습니다 List(차이점은 Set은 반복 값을 허용하지 않는다는 것입니다)

import java.util.Collection;
import java.util.HashSet;
import java.util.Arrays;

class Repeated {
      public static void main( String  [] args ) {

          Collection<String> listOne = Arrays.asList("milan","iga",
                                                    "dingo","iga",
                                                    "elpha","iga",
                                                    "hafil","iga",
                                                    "meat","iga", 
                                                    "neeta.peeta","iga");

          Collection<String> listTwo = Arrays.asList("hafil",
                                                     "iga",
                                                     "binga", 
                                                     "mike", 
                                                     "dingo","dingo","dingo");

          Collection<String> similar = new HashSet<String>( listOne );
          Collection<String> different = new HashSet<String>();
          different.addAll( listOne );
          different.addAll( listTwo );

          similar.retainAll( listTwo );
          different.removeAll( similar );

          System.out.printf("One:%s%nTwo:%s%nSimilar:%s%nDifferent:%s%n", listOne, listTwo, similar, different);
      }
}

산출:

$ java Repeated
One:[milan, iga, dingo, iga, elpha, iga, hafil, iga, meat, iga, neeta.peeta, iga]

Two:[hafil, iga, binga, mike, dingo, dingo, dingo]

Similar:[dingo, iga, hafil]

Different:[mike, binga, milan, meat, elpha, neeta.peeta]

필요한 작업을 정확히 수행하지 못하는 경우 여기에서 처리 할 수 ​​있도록 좋은 시작을 제공합니다.

독자를위한 질문 : 반복되는 모든 값을 어떻게 포함 하시겠습니까?


@Oscar, 내 정확한 생각이지만의 내용을 수정할 수 있는지 확실하지 listOne않지만 어쨌든 +1!
Anthony Forloney 2010 년

@poygenelubricants 제네릭이 아닌 원시 유형 이란 무엇을 의미 합니까? 왜 안돼?
OscarRyz

오스카, 업데이트 된 내 질문 봤어? 반복되는 값을 지원합니까?
user238384 2010 년

@Oscar : java.sun.com/docs/books/jls/third_edition/html/… "Java 프로그래밍 언어에 일반성을 도입 한 후 작성된 코드에서 원시 유형을 사용하는 것은 강력히 권장하지 않습니다. 향후 버전의 Java 프로그래밍 언어는 원시 유형의 사용을 허용하지 않습니다. "
polygenelubricants 2010 년

2
@polygenelubricants 답변이 중복 및 원시 유형을 처리하도록 업데이트되었습니다. 자바의 .. 미래 버전 인 BTW 는 결코 일어나지 않을 것입니다. ;)
OscarRyz


9

목록 이 실제로 목록 (순서, 중복 포함)입니까 , 아니면 세트 입니까 (순서 없음, 중복 없음)?

후자의 경우 a를 java.util.HashSet<E>사용하고 편리한 retainAll.

    List<String> list1 = Arrays.asList(
        "milan", "milan", "iga", "dingo", "milan"
    );
    List<String> list2 = Arrays.asList(
        "hafil", "milan", "dingo", "meat"
    );

    // intersection as set
    Set<String> intersect = new HashSet<String>(list1);
    intersect.retainAll(list2);
    System.out.println(intersect.size()); // prints "2"
    System.out.println(intersect); // prints "[milan, dingo]"

    // intersection/union as list
    List<String> intersectList = new ArrayList<String>();
    intersectList.addAll(list1);
    intersectList.addAll(list2);
    intersectList.retainAll(intersect);
    System.out.println(intersectList);
    // prints "[milan, milan, dingo, milan, milan, dingo]"

    // original lists are structurally unmodified
    System.out.println(list1); // prints "[milan, milan, iga, dingo, milan]"
    System.out.println(list2); // prints "[hafil, milan, dingo, meat]"

글쎄, 나는 그것이 어떤 데이터 구조 여야하는지 정말로 모른다. 중복이 있습니다. 이제 업데이트 된 질문을 볼 수 있습니다
user238384

데이터 세트에서 반복되는 값을 제거합니까? coz 나는 어떤 가치도 잃고 싶지 않다 :(
user238384

@agazerboy : 두 가지 질문을 모두 해결하려고 노력했습니다. 더 많은 설명을 요청하십시오.
polygenelubricants 2010 년

감사합니다 폴리. 예를 들어 "iga"를 두 번 추가 한 첫 번째 목록에서 중복으로 프로그램을 시도했지만 여전히 대답으로 3을 반환합니다. 지금은 4가되어야합니다. coz 목록 1에는 4 개의 유사한 값이 있습니다. 한 항목을 여러 번 추가하면 작동합니다. 당신은 무엇을 말합니까? 다른 데이터 구조?
user238384 2010 년

6

Java 8 removeIf 사용

public int getSimilarItems(){
    List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta");
    List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection
    int initial = two.size();

    two.removeIf(one::contains);
    return initial - two.size();
}

괜찮아 보이지만 목록을 수정하지 않고 유지하려면 목록 중 하나를 복제해야하며 특정 경우에는 바람직하지 않습니다.
Sebastian D' Agostino

6

두 컬렉션의 동등성을 테스트하는 편리한 방법을 찾고 있다면 org.apache.commons.collections.CollectionUtils.isEqualCollection순서에 관계없이 두 컬렉션을 비교하는를 사용할 수 있습니다 .


4

모든 접근 방식 중에서 사용 org.apache.commons.collections.CollectionUtils#isEqualCollection하는 것이 가장 좋은 접근 방식입니다. 이유는 다음과 같습니다.

  • 추가 목록 / 설정을 직접 선언 할 필요가 없습니다.
  • 입력 목록을 변경하지 않습니다.
  • 매우 효율적입니다. O (N) 복잡성의 동등성을 확인합니다.

apache.commons.collections종속성 으로 가질 수없는 경우 효율성 때문에 목록의 동일성을 확인하기 위해 따르는 알고리즘을 구현하는 것이 좋습니다.


3

간단한 솔루션 :-

    List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "d", "c"));
    List<String> list2 = new ArrayList<String>(Arrays.asList("b", "f", "c"));

    list.retainAll(list2);
    list2.removeAll(list);
    System.out.println("similiar " + list);
    System.out.println("different " + list2);

출력 :-

similiar [b, c]
different [f]

1

가정 hash1하고hash2

List< String > sames = whatever
List< String > diffs = whatever

int count = 0;
for( String key : hash1.keySet() )
{
   if( hash2.containsKey( key ) ) 
   {
      sames.add( key );
   }
   else
   {
      diffs.add( key );
   }
}

//sames.size() contains the number of similar elements.

그는 얼마나 많은 키가 동일한지가 아니라 동일한 키의 목록을 원합니다. 나는 생각한다.
Rosdi Kasim

도움을 주셔서 감사합니다 스테판. 그래 Rosdi가 맞고 당신도 마찬가지입니다. 유사한 값과 유사한 값의 총 수가 필요합니다.
user238384 2010 년

1

I은 목록 비교의 아주 기본적인 예를 찾을 비교 목록을 확인 먼저하고 다른 한 목록의 특정 요소의 가용성을 크기를 검증이 예.


-1
public static boolean compareList(List ls1, List ls2){
    return ls1.containsAll(ls2) && ls1.size() == ls2.size() ? true :false;
     }

public static void main(String[] args) {

    ArrayList<String> one = new ArrayList<String>();
    one.add("one");
    one.add("two");
    one.add("six");

    ArrayList<String> two = new ArrayList<String>();
    two.add("one");
    two.add("six");
    two.add("two");

    System.out.println("Output1 :: " + compareList(one, two));

    two.add("ten");

    System.out.println("Output2 :: " + compareList(one, two));
  }

1
이 솔루션은 2 개에 "one"의 3 개 사본이 포함 된 경우 잘못된 결과를 반환합니다. 실제 결과가 잘못 생성됩니다.
Joseph Fitzgerald

이 부분에 감사드립니다 : && ls1.size () == ls2.size ()
Nouar

1
? true :false스 니펫에 필요 하다고 생각하는 이유가 있습니까?
Krzysztof Tomaszewski
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.