C #의 'yield'키워드에 해당하는 Java가 있습니까?
Java 자체 수준 높은 수준이라고할까요?
정말 편리합니다. 현재 저는 수율이있는 약 5 줄의 코드 인 트리의 모든 노드를 생성하는 반복기를 구현하고 싶습니다.
내가 아는 두 가지 옵션 은 2007의 Aviad Ben Dov의 infomancers-collections 라이브러리 와 2008의 Jim Blackler의 YieldAdapter 라이브러리입니다 (다른 답변 참조 됨).
둘 다 yield return
Java에서 -like 구조로 코드를 수 있으므로 둘 다 요청을받을 것입니다. 둘 사이의 주목할만한 차이점은 다음과 같다.
역학
Aviad의 라이브러리는 바이트 코드 조작을 사용하고 Jim은 멀티 스레딩을 사용합니다. 필요에 따라 각각의 장점과 단점이 있습니다. Aviad의 솔루션은 더 빠르지 만 Jim은 더 이식성이 뛰어납니다 (예를 들어, Aviad의 라이브러리가 Android에서 작동하지 않을 생각합니다).
상호 작용
Aviad의 라이브러리에는 더 깔끔한 인터페이스가 있습니다. 예를 들면 다음과 같습니다.
Iterable<Integer> it = new Yielder<Integer>() {
@Override protected void yieldNextCore() {
for (int i = 0; i < 10; i++) {
yieldReturn(i);
if (i == 5) yieldBreak();
}
}
};
Jim 's는 훨씬 복잡하지만 방법이 adept
있는 제네릭 Collector
을 요구합니다 collect(ResultHandler)
. 으. 그러나 Zoom 정보는 Jim의 코드에 의해 다음과 같은 것을 사용할 수 있습니다 .
Iterable<Integer> it = new Generator<Integer>() {
@Override protected void run() {
for (int i = 0; i < 10; i++) {
yield(i);
if (i == 5) return;
}
}
};
특허
Aviad의 솔루션은 BSD입니다.
Jim의 솔루션은 공개 도메인이라고 언급 한 래퍼도 마찬가지입니다.
이제 Java에는 Lambda가 있습니다. 다음과 같이 할 수 있습니다.
public Yielderable<Integer> oneToFive() {
return yield -> {
for (int i = 1; i < 10; i++) {
if (i == 6) yield.breaking();
yield.returning(i);
}
};
}
나는 두 가지 방법이 있습니다.
- 포팅하는 동안 쉽지 않은 바이트 코드;
yield
분명히 리소스 비용이 여러 기반 .
그러나 yield
C # 2.0+ 컴파일러가 yield return/break
생성을 위해 수행하는 작업에 가장 근접한 구현 인 자바 에서 생성기 를 구현하는 세 번째이자 아마도 가장 자연스러운 방법 인 lombok-pg가 있습니다. 완전히 상태 머신을 기반으로하며 javac
소스 코드 AST를 조작하기 위해 긴밀한 협력이 필요합니다 . 안타깝게도 lombok-pg 지원은 중단 된 것으로 보이며 (1 ~ 2 년 이상 저장소 활동이 없음) 안타깝게도 원래 Project Lombok 에는 yield
기능 이 부족합니다 (Eclipse, IntelliJ IDEA 지원과 같은 더 나은 IDE가 있습니다).
Stream.iterate (seed, seedOperator) .limit (n) .foreach (action) 은 yield 연산자와 동일하지 않지만 다음과 같이 고유 한 생성기를 작성하는 것이 유용 할 수 있습니다.
import java.util.stream.Stream;
public class Test01 {
private static void myFoo(int someVar){
//do some work
System.out.println(someVar);
}
private static void myFoo2(){
//do some work
System.out.println("some work");
}
public static void main(String[] args) {
Stream.iterate(1, x -> x + 1).limit(15).forEach(Test01::myFoo); //var1
Stream.iterate(1, x -> x + 1).limit(10).forEach(item -> myFoo2()); //var2
}
}
또한 Observable을 "yielder"로 사용하기 위해 프로젝트에서 RXJava 를 이미 사용하고 있는지도 제안합니다 . 자신 만의 Observable을 만들면 비슷한 방식으로 사용할 수 있습니다.
public class Example extends Observable<String> {
public static void main(String[] args) {
new Example().blockingSubscribe(System.out::println); // "a", "b", "c", "d"
}
@Override
protected void subscribeActual(Observer<? super String> observer) {
observer.onNext("a"); // yield
observer.onNext("b"); // yield
observer.onNext("c"); // yield
observer.onNext("d"); // yield
observer.onComplete(); // finish
}
}
Observable은 반복자로 변환되어 더 전통적인 for 루프에서도 사용할 수 있습니다. 또한 RXJava는 정말 강력한 도구를 제공하지만 간단한 것만 필요하다면 과잉 일 수도 있습니다.
참고 URL : https://stackoverflow.com/questions/1980953/is-there-a-java-equivalent-to-cs-yield-keyword
'IT' 카테고리의 다른 글
시맨틱 차이 유틸리티 (0) | 2020.08.15 |
---|---|
JWT 토큰의 서버 측 처리를위한 모범 사례 (0) | 2020.08.15 |
GCC 및 ld로 사용하지 않는 C / C ++ 기호를 제거하는 방법은 무엇입니까? (0) | 2020.08.14 |
Rails 및 HTTParty를 사용하여 API에 JSON 게시 (0) | 2020.08.14 |
LastPass가 양식 작성 중지 (0) | 2020.08.14 |