developer tip

Java 비교 두 목록

optionbox 2020. 9. 18. 08:05
반응형

Java 비교 두 목록


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

예를 들면

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

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

그렇다면 해시 맵을 사용해야하는 경우 결과를 얻는 방법은 무엇입니까?

도와주세요

추신 : 학교 과제가 아닙니다 :) 그래서 당신이 나를 안내하면 충분할 것입니다


편집하다

다음은 두 가지 버전입니다. 하나 사용 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]

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

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


에서 시도 intersection()하고 subtract()방법을 사용할 수 있습니다 CollectionUtils.

intersection() method gives you a collection containing common elements and the subtract() method gives you all the uncommon ones.

They should also take care of similar elements


Are these really lists (ordered, with duplicates), or are they sets (unordered, no duplicates)?

Because if it's the latter, then you can use, say, a java.util.HashSet<E> and do this in expected linear time using the convenient 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]"

Using 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();
}

Simple solution :-

    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);

Output :-

similiar [b, c]
different [f]

If you are looking for a handy way to test the equality of two collections, you can use org.apache.commons.collections.CollectionUtils.isEqualCollection, which compares two collections regardless of the ordering.


Assuming hash1 and 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.

I found a very basic example of List comparison at List Compare This example verifies the size first and then checks the availability of the particular element of one list in another.


Of all the approaches, I find using org.apache.commons.collections.CollectionUtils#isEqualCollection is the best approach. Here are the reasons -

  • I don't have to declare any additional list/set myself
  • I am not mutating the input lists
  • It's very efficient. It checks the equality in O(N) complexity.

If it's not possible to have apache.commons.collections as a dependency, I would recommend to implement the algorithm it follows to check equality of the list because of it's efficiency.


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));
  }

참고URL : https://stackoverflow.com/questions/2762093/java-compare-two-lists

반응형