한 목록에 다른 요소가 포함되어 있는지 확인
개체가 다른 두 개의 목록이 있습니다.
List<Object1> list1;
List<Object2> list2;
특정 속성 (Object1 및 Object2에는 (다른 것 중에서), 하나의 상호 속성 (Long 유형 포함), attributeSame이라는 이름의)을 기반으로 list1의 요소가 list2에 있는지 확인하고 싶습니다.
지금은 이렇게합니다.
boolean found = false;
for(Object1 object1 : list1){
for(Object2 object2: list2){
if(object1.getAttributeSame() == object2.getAttributeSame()){
found = true;
//also do something
}
}
if(!found){
//do something
}
found = false;
}
그러나 나는 이것을하는 더 좋고 더 빠른 방법이 있다고 생각합니다 :) 누군가 그것을 제안 할 수 있습니까?
감사!
기본 동등성을 테스트해야하는 경우 한 줄의 입력 목록을 수정하지 않고 기본 JDK로 수행 할 수 있습니다.
!Collections.disjoint(list1, list2);
특정 속성을 테스트해야하는 경우 더 어렵습니다. 기본적으로
list1.stream()
.map(Object1::getProperty)
.anyMatch(
list2.stream()
.map(Object2::getProperty)
.collect(toSet())
::contains)
... 이는 고유 한 값을 수집하고 list2
각 값의 list1
존재 여부를 테스트합니다 .
Apache Commons CollectionUtils를 사용할 수 있습니다 .
if(CollectionUtils.containsAny(list1,list2)) {
// do whatever you want
} else {
// do other thing
}
이것은 사용자 정의 개체에 대해 같음 기능을 적절하게 오버로드했다고 가정합니다.
이 하나의 방법 의 Collection
이름은 retainAll
있지만, 일부 가진 부작용 당신을 위해 참조
지정된 컬렉션에 포함 된이 목록의 요소 만 유지합니다 (선택적 작업). 즉, 지정된 컬렉션에 포함되지 않은 모든 요소를이 목록에서 제거합니다.
이 목록이 호출의 결과로 변경된 경우 true
같은
boolean b = list1.retainAll(list2);
Loius 대답이 맞습니다. 예를 추가하고 싶습니다.
listOne.add("A");
listOne.add("B");
listOne.add("C");
listTwo.add("D");
listTwo.add("E");
listTwo.add("F");
boolean noElementsInCommon = Collections.disjoint(listOne, listTwo); // true
Narendra의 논리를 줄이려면 다음을 사용할 수 있습니다.
boolean var = lis1.stream().anyMatch(element -> list2.contains(element));
더 빠른 방법은 추가 공간이 필요합니다.
예를 들면 :
한 목록의 모든 항목을 HashSet에 넣습니다 (object.getAttributeSame ()을 사용하려면 직접 해시 함수를 구현해야 함)
Go through the other list and check if any item is in the HashSet.
In this way each object is visited at most once. and HashSet is fast enough to check or insert any object in O(1).
According to the JavaDoc for the .contains(Object obj)
:
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
So if you override your .equals()
method for your given object, you should be able to do: if(list1.contains(object2))...
If the elements will be unique (ie. have different attributes) you could override the .equals()
and .hashcode()
and store everything in HashSets
. This will allow you to check if one contains another element in constant time.
to make it faster, you can add a break; that way the loop will stop if found is set to true:
boolean found = false;
for(Object1 object1 : list1){
for(Object2 object2: list2){
if(object1.getAttributeSame() == object2.getAttributeSame()){
found = true;
//also do something
break;
}
}
if(!found){
//do something
}
found = false;
}
If you would have maps in stead of lists with as keys the attributeSame, you could check faster for a value in one map if there is a corresponding value in the second map or not.
Can you define the type of data you hold ? is it big data ? is it sorted ? I think that you need to consider different efficiency approaches depending on the data.
For example, if your data is big and unsorted you could try and iterate the two lists together by index and store each list attribute in another list helper. then you could cross check by the current attributes in the helper lists.
good luck
edited : and I wouldn't recommend overloading equals. its dangerous and probably against your object oop meaning.
org.springframework.util.CollectionUtils
boolean containsAny(java.util.Collection<?> source, java.util.Collection<?> candidates)
Return true if any element in 'candidates' is contained in 'source'; otherwise returns false
With java 8
, we can do like below to check if one list contains any element of other list
boolean var = lis1.stream().filter(element -> list2.contains(element)).findFirst().isPresent();
참고URL : https://stackoverflow.com/questions/11796371/check-if-one-list-contains-element-from-the-other
'Programing' 카테고리의 다른 글
C #을 사용하여 .net에서 RSS 피드를 읽는 가장 좋은 방법 (0) | 2020.08.29 |
---|---|
Spring MVC 테스트에서“Circular view path”예외를 피하는 방법 (0) | 2020.08.29 |
Vue.js를 다른 페이지로 리디렉션 (0) | 2020.08.29 |
부모의 jQuery 부모 (0) | 2020.08.29 |
Xcode에서 후행 공백 제거 (0) | 2020.08.29 |