Java List.contains(필드 값이 x와 동일한 개체)
가 있는지 요.List
에는 특정 값을 가진 필드가 있는 객체가 포함되어 있습니다.루프를 사용해서 확인할 수는 있지만, 더 효율적인 코드가 없을까 궁금했어요.
예를 들면,
if(list.contains(new Object().setName("John"))){
//Do some stuff
}
위의 코드는 아무것도 하지 않고, 단지 내가 달성하려고 하는 것을 대략적으로 보여주기 위한 것입니다.
또, 심플 루프를 사용하지 않는 이유는, 이 코드가 현재 루프내의 루프내에 들어가 있기 때문입니다.읽기 쉽도록 이 루프에 루프를 추가하고 싶지 않습니다.그래서 나는 간단한 대안이 없을까 생각했다.
스트림
Java 8 을 사용하고 있는 경우는, 다음과 같은 것을 시험해당 방법은 다음과 같습니다.
public boolean containsName(final List<MyObject> list, final String name){
return list.stream().filter(o -> o.getName().equals(name)).findFirst().isPresent();
}
또는 다음과 같은 방법을 사용할 수 있습니다.
public boolean containsName(final List<MyObject> list, final String name){
return list.stream().map(MyObject::getName).filter(name::equals).findFirst().isPresent();
}
됩니다.true
List<MyObject>
에는 를 contains contains a a가 되어 있습니다.MyObject
는 with with with with with with with with 라는 이름으로name
에 하는 경우MyObject
를 참조해 주세요.getName().equals(name)
을 사용하다
public void perform(final List<MyObject> list, final String name){
list.stream().filter(o -> o.getName().equals(name)).forEach(
o -> {
//...
}
);
}
서 ★★★★★o
.MyObject
★★★★★★ 。
MK10에서 제안하는 바와 같이, 「MK10」()Stream#anyMatch
★★★★
public boolean containsName(final List<MyObject> list, final String name){
return list.stream().anyMatch(o -> o.getName().equals(name));
}
두 가지 선택이 있습니다.
1. 오브젝트 클래스의 "equals()" 메서드를 덮어쓰는 것이 바람직합니다.
예를 들어 다음과 같은 오브젝트 클래스가 있다고 합시다.
public class MyObject {
private String name;
private String location;
//getters and setters
}
이제 MyObject 이름에만 관심이 있다고 칩시다.MyObject 이름이 고유해야 합니다.그러면 두 개의 MyObject가 같은 이름을 가지고 있으면 동일한 이름으로 간주됩니다.이 경우 이름을 비교하여 동등성을 판단하도록 'equals' 메서드(및 'hashcode' 메서드)를 덮어쓸 수 있습니다.
이렇게 하면 다음과 같이 컬렉션에 "foo"라는 이름의 MyObject가 포함되어 있는지 확인할 수 있습니다.
MyObject object = new MyObject();
object.setName("foo");
collection.contains(object);
단, 다음과 같은 경우에는 이 옵션이 적용되지 않을 수 있습니다.
- 이름과 위치를 모두 사용하여 동일성을 확인하지만 컬렉션에 특정 위치를 가진 "MyObject"가 있는지 확인하려고 합니다.이 경우 이미 "equals()"를 덮어씁니다.
- MyObject는 변경할 수 없는 API의 일부입니다.
다음 중 하나의 경우 옵션2가 필요합니다.
2. 독자적인 유틸리티 메서드를 작성합니다.
public static boolean containsLocation(Collection<MyObject> c, String location) {
for(MyObject o : c) {
if(o != null && o.getLocation.equals(location)) {
return true;
}
}
return false;
}
또는 ArrayList(또는 다른 컬렉션)를 확장한 후 독자적인 메서드를 추가할 수도 있습니다.
public boolean containsLocation(String location) {
for(MyObject o : this) {
if(o != null && o.getLocation.equals(location)) {
return true;
}
}
return false;
}
불행하게도 더 나은 방법은 없다.
Java 8+ 를 사용하는 방법은 다음과 같습니다.
boolean isJohnAlive = list.stream().anyMatch(o -> "John".equals(o.getName());
구글 구아바
Guava를 사용하는 경우 기능적으로 접근하여 다음을 수행할 수 있습니다.
FluentIterable.from(list).find(new Predicate<MyObject>() {
public boolean apply(MyObject input) {
return "John".equals(input.getName());
}
}).Any();
에 검색마다 할 수 .그러나 술어는 개체이므로 검색마다 다른 변형을 제공할 수 있습니다.라이브러리 자체가 컬렉션의 반복과 적용하려는 함수를 어떻게 구분하는지 주목하십시오. 덮어쓸 는 없습니다.equals()
특정 행동에 대한 것입니다.
다음과 같이 java.util.Java 8 이상에 내장된 스트림 프레임워크는 유사한 기능을 제공합니다.
Collection.contains()
합니다.equals()
될 때까지 각 true
.
이것을 중 는 우선으로 하는 입니다.equals()
이치
따라서 Guava와 같은 프레임워크는 이에 대해 술어를 사용합니다.와 함께Iterables.find(list, predicate)
는, 테스트를 술어에 넣는 것으로써, 임의의 필드를 검색할 수 있습니다.
VM 위에 내장된 다른 언어에는 이 기능이 내장되어 있습니다.예를 들어 Groovy에서는 다음과 같이 적습니다.
def result = list.find{ it.name == 'John' }
Java 8은 우리의 모든 삶을 편하게 해주었습니다.
List<Foo> result = list.stream()
.filter(it -> "John".equals(it.getName())
.collect(Collectors.toList());
이런 걸 신경 쓴다면 '자바를 넘어서'라는 책을 추천해요.자바의 수많은 단점들과 다른 언어들이 어떻게 더 잘 할 수 있는지에 대한 많은 예들이 포함되어 있다.
바이너리 검색
Collections.binarySearch를 사용하여 목록 내의 요소를 검색할 수 있습니다(목록이 정렬되어 있는 경우).
Collections.binarySearch(list, new YourObject("a1", "b",
"c"), new Comparator<YourObject>() {
@Override
public int compare(YourObject o1, YourObject o2) {
return o1.getName().compareTo(o2.getName());
}
});
않은 경우 음수가 됩니다.index
할 수 .이를 통해 서로 다른 검색 전략을 가진 개체를 검색할 수 있습니다.
지도
해서 만들 수 요.Hashmap<String, Object>
값중, 그 에 '어느 정도인지', '어느 정도인지', '어느 정도인지', '어느 정도인지', '어느 정도인지', '어느 정도인지', '어느 정도인지', '어느 정도인지', '어느 정도인지'를 볼 수 있습니다.yourHashMap.keySet().contains(yourValue)
true가 됩니다.
이클립스 컬렉션
Eclipse 컬렉션을 사용하는 경우anySatisfy()
이렇게 하다, , 쓰다, 쓰다, 쓰다, 쓰다, 하다.List
in a a a a ListAdapter
바꿀 수도 요.List
ListIterable
가능하면.
ListIterable<MyObject> list = ...;
boolean result =
list.anySatisfy(myObject -> myObject.getName().equals("John"));
이러한 작업을 자주 수행할 경우 유형에 속성이 있는지 여부를 응답하는 메서드를 추출하는 것이 좋습니다.
public class MyObject
{
private final String name;
public MyObject(String name)
{
this.name = name;
}
public boolean named(String name)
{
return Objects.equals(this.name, name);
}
}
할 수 있습니다.anySatisfyWith()
메서드 참조와 함께.
boolean result = list.anySatisfyWith(MyObject::named, "John");
변경할 수 없는 경우List
에ListIterable
를 사용하는 방법은 다음과 같습니다.ListAdapter
.
boolean result =
ListAdapter.adapt(list).anySatisfyWith(MyObject::named, "John");
주의: 저는 이클립스 선정의 커밋자입니다.
Predicate
Java 8 또는 컬렉션을 처리하는 데 더 많은 기능을 제공하는 라이브러리를 사용하지 않으면 솔루션보다 더 재사용 가능한 기능을 구현할 수 있습니다.
interface Predicate<T>{
boolean contains(T item);
}
static class CollectionUtil{
public static <T> T find(final Collection<T> collection,final Predicate<T> predicate){
for (T item : collection){
if (predicate.contains(item)){
return item;
}
}
return null;
}
// and many more methods to deal with collection
}
저는 이런 것을 사용하고 있습니다. 술어 인터페이스를 가지고 있고, 그것을 구현한 것을 util 클래스에 전달하고 있습니다.
내 방식대로 하면 어떤 이점이 있습니까?모든 유형의 컬렉션에서 검색을 처리하는 한 가지 방법이 있습니다.다른 필드로 검색하려면 별도의 메서드를 작성할 필요가 없습니다.필요한 것은 다른 술어를 지정하는 것입니다.이 술어는 더 이상 쓸모가 없어지면 바로 파기될 수 있습니다.
만약 당신이 그것을 사용하고 싶다면, 당신이 해야 할 모든 것은 호출 방식을 정의하고 tyour 술어를 정의하는 것입니다.
CollectionUtil.find(list, new Predicate<MyObject>{
public boolean contains(T item){
return "John".equals(item.getName());
}
});
여기 Guava를 사용한 솔루션이 있습니다.
private boolean checkUserListContainName(List<User> userList, final String targetName){
return FluentIterable.from(userList).anyMatch(new Predicate<User>() {
@Override
public boolean apply(@Nullable User input) {
return input.getName().equals(targetName);
}
});
}
contains
메서드 사용equals
내부적으로그래서 넌 이 모든 걸 덮어쓸 필요가 있어equals
당신의 필요에 따라 당신의 수업을 위한 방법.
그러나 이것은 구문적으로 정확해 보이지 않습니다.
new Object().setName("John")
이 작업을 수행해야 하는 경우List.contains(Object with field value equal to x)
단순하고 효율적인 회피책은 다음과 같습니다.
List<field obj type> fieldOfInterestValues = new ArrayList<field obj type>;
for(Object obj : List) {
fieldOfInterestValues.add(obj.getFieldOfInterest());
}
그 다음에List.contains(Object with field value equal to x)
같은 결과를 얻을 수 있다fieldOfInterestValues.contains(x);
JAVA 8 SDK에도 불구하고 http://commons.apache.org/proper/commons-collections/과 같은 많은 수집 도구가 있습니다.
Predicate condition = new Predicate() {
boolean evaluate(Object obj) {
return ((Sample)obj).myField.equals("myVal");
}
};
List result = CollectionUtils.select( list, condition );
언급URL : https://stackoverflow.com/questions/18852059/java-list-containsobject-with-field-value-equal-to-x
'IT이야기' 카테고리의 다른 글
플레인 VueJS 프로젝트에서 Typescript 함수 사용 (0) | 2022.07.12 |
---|---|
vuex: 알 수 없는 getter: 기사 (0) | 2022.07.12 |
.c 및 .h 파일 확장자는 C에게 어떤 의미입니까? (0) | 2022.07.12 |
부울 필드의 경우 getter/setter 명명 규칙은 무엇입니까? (0) | 2022.07.12 |
솔과 루센의 차이 (0) | 2022.07.12 |