먼저 일반적인 경우 : 플래그를 사용하여 컬렉션의 일부 요소가 특정 조건을 충족하는지 확인하는 것은 드문 일이 아닙니다. 그러나이 문제를 해결하기 위해 가장 자주 본 패턴은 추가 방법으로 검사를 이동하고 직접 반환합니다 (Kilian Foth가 답변에 설명 된 것처럼 ).
private <T> boolean checkCollection(Collection<T> collection)
{
for (T element : collection)
if (checkElement(element))
return true;
return false;
}
Java 8부터 Stream.anyMatch(…)
다음을 사용하는 더 간결한 방법이 있습니다 .
collection.stream().anyMatch(this::checkElement);
귀하의 경우 이것은 아마도 다음과 같이 보일 것입니다 ( list == entry.getValue()
질문에서 가정 ) :
map.values().stream().anyMatch(list -> list.size() > limit);
특정 예의 문제는에 대한 추가 호출 fillUpList()
입니다. 답은이 방법이 무엇을해야하는지에 달려 있습니다.
참고 사항 : 현재 호출 fillUpList()
중인 요소에 의존하지 않기 때문에 호출 은 의미가 없습니다. 나는 이것이 질문 형식에 맞게 실제 코드를 제거 한 결과라고 생각합니다. 그러나 정확하게 해석하기 어렵고 추론하기 어려운 인공적인 예가됩니다. 따라서 Minimal, Complete 및 Verifiable 예제 를 제공하는 것이 매우 중요합니다 .
따라서 실제 코드는 전류 entry
를 메소드에 전달한다고 가정합니다 .
그러나 더 많은 질문이 있습니다 :
- 이 코드에 도달하기 전에지도의 목록이 비어 있습니까? 그렇다면 왜 목록이나
BigInteger
키 세트가 아닌 이미 맵이 있습니까? 비어 있지 않으면 왜 목록 을 작성 해야 합니까? 목록에 이미 요소가있는 경우이 경우 업데이트 또는 다른 계산이 아닙니까?
- 목록이 한계보다 커지게하는 원인은 무엇입니까? 이것은 오류 상태입니까, 아니면 자주 발생할 것으로 예상됩니까? 잘못된 입력으로 인한 것입니까?
- 한계보다 큰 목록에 도달 할 때까지 계산 된 목록이 필요합니까?
- " 뭔가 "부분은 무엇을합니까?
- 이 부분 후에 충전재를 다시 시작합니까?
이것은 코드 조각을 이해하려고 할 때 떠오른 몇 가지 질문입니다. 제 생각에는 이것이 실제 코드 냄새입니다 . 코드가 의도를 명확하게 전달하지 않습니다.
다음을 의미 할 수 있습니다 ( "모두 또는 아무것도 없음". 한계에 도달하면 오류를 나타냄).
/**
* Computes the list of all foo strings for each passed number.
*
* @param numbers the numbers to process. Must not be {@code null}.
* @return all foo strings for each passed number. Never {@code null}.
* @throws InvalidArgumentException if any number produces a list that is too long.
*/
public Map<BigInteger, List<String>> computeFoos(Set<BigInteger> numbers)
throws InvalidArgumentException
{
if (numbers.isEmpty())
{
// Do you actually need to log this here?
// The caller might know better what to do in this case...
logger.info("Nothing to compute");
}
return numbers.stream().collect(Collectors.toMap(
number -> number,
number -> computeListForNumber(number)));
}
private List<String> computeListForNumber(BigInteger number)
throws InvalidArgumentException
{
// compute the list and throw an exception if the limit is exceeded.
}
또는 다음과 같은 의미 일 수 있습니다 ( "첫 번째 문제까지 업데이트").
/**
* Refreshes all foo lists after they have become invalid because of bar.
*
* @param map the numbers with all their current values.
* The values in this map will be modified.
* Must not be {@code null}.
* @throws InvalidArgumentException if any new foo list would become too long.
* Some other lists may have already been updated.
*/
public void updateFoos(Map<BigInteger, List<String>> map)
throws InvalidArgumentException
{
map.replaceAll(this::computeUpdatedList);
}
private List<String> computeUpdatedList(
BigInteger number, List<String> currentValues)
throws InvalidArgumentException
{
// compute the new list and throw an exception if the limit is exceeded.
}
또는 ( "모든 목록을 업데이트하지만 너무 큰 경우 원본 목록을 유지하십시오") :
/**
* Refreshes all foo lists after they have become invalid because of bar.
* Lists that would become too large will not be updated.
*
* @param map the numbers with all their current values.
* The values in this map will be modified.
* Must not be {@code null}.
* @return {@code true} if all updates have been successful,
* {@code false} if one or more elements have been skipped
* because the foo list size limit has been reached.
*/
public boolean updateFoos(Map<BigInteger, List<String>> map)
{
boolean allUpdatesSuccessful = true;
for (Entry<BigInteger, List<String>> entry : map.entrySet())
{
List<String> newList = computeListForNumber(entry.getKey());
if (newList.size() > limit)
allUpdatesSuccessful = false;
else
entry.setValue(newList);
}
return allUpdatesSuccessful;
}
private List<String> computeListForNumber(BigInteger number)
{
// compute the new list
}
또는 다음조차도 ( computeFoos(…)
첫 번째 예제에서 사용 하지만 예외는 없음) :
/**
* Processes the passed numbers. An optimized algorithm will be used if any number
* produces a foo list of a size that justifies the additional overhead.
*
* @param numbers the numbers to process. Must not be {@code null}.
*/
public void process(Collection<BigInteger> numbers)
{
Map<BigInteger, List<String>> map = computeFoos(numbers);
if (isLimitReached(map))
processLarge(map);
else
processSmall(map);
}
private boolean isLimitReached(Map<BigInteger, List<String>> map)
{
return map.values().stream().anyMatch(list -> list.size() > limit);
}
아니면 완전히 다른 것을 의미 할 수도 있습니다 ... ;-)