2016-11-04 2 views
0

저는 현재 Java를 배우고 있으며 수동으로 for 루프를 사용하는 대신 list foreach 메서드를 사용하는 방법을 배우는 데 관심이 있습니다. 나는 그들이 같은 것을 수행 할 수 있다고 생각한다.for() for for 대신 List Foreach 사용

나의 현재 코드는 다음과 같습니다

while(!this.cards.isEmpty()) { 
    for(int i = 0; i < this.table.GetPlayerCount() && !this.cards.isEmpty(); i++) { 
    DealOneCardToPlayer(this.table.players.get(i) ,this.cards.get(0)); 
    this.cards.remove(0); 
    } 
} 

내가 거기에 이런 걸 사용하는 방법이라고 생각 :

this.cards.foreach() { do suff } 

을하지만 난 꽤을 잡을 수 없어 구문 ... 누군가가 나에게 빠른 손을 줄 수 있습니까?

+0

'for (...) '의 추가 조건은 이것이'for' 루프가 아니라는 것을 의미합니다. 'forEach'를 사용하는 법을 배우려는 경우, 이것은 배우기에 좋은 예제는 아닙니다. – khelwood

+1

루프에서 카드를 제거 할 필요는 없습니다. 대신에'this.cards.iterator()'를 사용하면, 다음 카드를 지우지 않고 다음 카드를 얻을 수 있습니다. (원한다면 나중에'this.cards.clear()'를 호출 할 수 있습니다). –

+0

글쎄, 나는 '현실 세계'의 권리를 모델링하는 법을 배우려고하고있다. 그래서 딜러가이 루프가하고있는 '갑판'에서 카드를 다루고있을 때. 카드가 플레이어에게 주어지면 카드는 '데크'에서 '제거'됩니다. 나는 그것을 유지하고 싶습니다 - 코드가 작동 중입니다 - 나는 단지 그것을 표현하는보다 간결한 방법을 찾고 있었으며 foreach가 그럴 것이라고 생각했습니다. @ user902383 왜 내가 여기 foreach를 사용할 수 있다고 생각하지 않는다고합니까? – Jeff

답변

2

나는 당신이 카드의 인덱스를 반복하여 할 수 있다고 생각 : 당신이가는대로 카드를 제거하지 않습니다이 있지만

IntStream.range(0, this.cards.size()).forEach(idx -> { 
    DealOneCardToPlayer(
     this.table.players.get(idx % this.table.GetPlayerCount()), 
     this.cards.get(idx)); 
}); 

; 당신이 정말로 this.cards 필요하면 후 비어 :

this.cards.clear(); 

당신이 (예를 들어 당신이 각 플레이어에 N 카드를 처리 할) 카드의 수는 밖으로 처리 제한하려면, 가장 쉬운 방법은 추출하는 것입니다 하위 목록은 다음 바로 위와 같은 방법을 적용

List<Card> cardsToDeal = this.cards.subList(0, numCardsToDeal); 
IntStream.range(0, cardsToDeal.size()).forEach(idx -> { 
    DealOneCardToPlayer(
     this.table.players.get(idx % this.table.GetPlayerCount()), 
     cardsToDeal.get(idx)); 
}); 
cardsToDeal.clear(); 
+1

'zipWithIndex'가 트릭을 할 또 다른 예입니다. –

+0

잘 그렇습니다 - 나는 '처분'된 카드를 가지고 있기 위해 카드의 '데크'가 필요합니다. 그러나 이것이 현재 '갑판'보다 적은 수의 카드를 처리하는 것은 아니지만, 결국은 결국 사용하게됩니다. 그래서 나는 this.cards.clear(); 그 생각을위한 올바른 움직임이 될까요? – Jeff

+0

나는 당신이 생각하는 문제를 이해하지 못한다. 이것은 카드가있는만큼 많은 카드를 다룬다 (카드가 동시에 다른 스레드에서 수정되지 않는다고 가정 할 때). 따라서 카드를 덱에서 "제거"하려면 카드를 반복하고 덱을 지우는 것은 반복 할 때 각 카드를 제거하는 것과 같은 효과가 있습니다. –

0

당신이 찾고있는 것은 람다 식입니다. foreach는 방법은 다음과 같이 사용할 수 있습니다 의미, 기능 인터페이스 (하나 개의 추상 메소드를 사용하여 인터페이스)를 취합니다

List<String> myList; 
    myList.forEach((String s) -> System.out.println(s)); 

출처 : 당신은 당신이 새로운 자바 8 스트림을 사용하고자하는 의미 http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html

0

당신의 명부. 당신은 스트림을 호출 할 수 있습니다

this.cards.stream().forEach(card -> {// do something here}); 

() 방법 대해 forEach()에 액세스하려면 다음

그래서 구문은 같다. 귀하의 목록에

또는 직접 :

this.cards.forEach(...); 

내 예제에서 나는 익명 클래스 (더 진화)의 보일러 판을 방지 할 수있는 편리한 방법입니다 새로운 자바 8 화살표 기능을 사용합니다.

당신은)를 대해 forEach (하는 방법을 전달할 수 있습니다 당신은 자바 8의 기능 API (및 람다)에 대해 얘기하고

this.cards.stream().forEach(doSomethingWithMyCard); 
+0

리스트 (모든 Iterable' even)는'forEach'를 직접 구현하기 때문에'stream(). forEach (...) '를 사용할 필요가 없습니다. –

+0

사실, Iterable은 메소드를 포함하고 있으며,'Map'은'# forEach'도 가지고 있습니다. 여러분은 BiConsumer ' – Rogue

+0

@ MarkRotteveel 맞습니다. 내 게시물을 업데이트합니다. –

1

.

기본적으로 람다는 함수/메소드의 속기형이며 입력 값과 잠재적으로 반환 값을 가지고 있습니다. #forEach의 경우 T (사용자의 목록 유형)을 허용하는 함수를 제공하고 아무 것도 반환하지 않습니다. 이를 Consumer이라고합니다. 그런 다음 메서드는 사용자가 지정한 Consumer을 가져와 목록의 각 요소에 대해 호출합니다.

는 동등성를 들어, 다음은 지금까지 개발할 때 우려로 본질적으로 같은 것입니다

void someConsumerMethod(Card c) { 
    //lambda code block 
} 


(Card c) -> //lambda code block 


this::someConsumerMethod //direct reference to the first method 

이 예는 다음과 같습니다 당신의 예를 적응으로

this.cards.forEach(c -> { 
    System.out.println(c); //fully expanded 
}); 
this.cards.forEach(c -> System.out.println(c)); //shorthand/one-liner 
//or, since println already matches a Consumer<Object>, we can method reference it! 
this.cards.forEach(System.out::println); 

, 나 같으면 컬렉션을 수정하는 동안 컬렉션을 수정하는 것이 좋습니다 (적어도 Iterator#remove을 사용하지 않고). Andy Turner의 대답은 이미 IntStream 응용 프로그램을 사용하여 원하는 색인을 반복하는 방법을 보여줍니다.

+0

예 람다 (Lambdas)가 내가 관심을 가지고 있었던 것이라고 생각합니다. 곧이 사진을 올리며 내가 무엇을 생각해 내는지 볼 것입니다. 감사합니다. 불량배. – Jeff

+0

함수 api도 람다의 "수신"끝에 관련되어 있기 때문에 API를 사용하여 브러시를 작성해야합니다. – Rogue

0

당신은 현재의 플레이어 인덱스를 추적하고, 카드 팩을 반복 수를 완전히 배포합니다 :

,429,332 10

당신이 유일한 선수 당 하나 개의 카드를 배포 할 경우, 교체로

if(playerIndex == this.table.GetPlayerCount()-1) 
    playerIndex = 0; 
    else 
    playerIndex = playerIndex + 1; 

:

if(playerIndex == this.table.GetPlayerCount()-1) 
    break; 
0

귀하의 예를 들어 당신이 모든을 가지고 있기 때문에 forEach 호출로 변환 할 정말 적합하지 않습니다 거기에 여분의 조건이 있습니다. 또한 for 루프에서 목록을 수정 중입니다. 이러한 이유로 인해 for 루프를 사용하는 것이 좋습니다.

forEach 목록의 개체를 변경하려는 경우 또는 목록의 각 항목에 액세스하려는 경우 호출을 사용할 수 있습니다.

구문은 다음과 같습니다 : 여기

list.forEach(item -> <insert the stuff you want to do to the item here>); 

forEach를 사용하는 방법을 보여주는 몇 가지 예입니다. 또한 for 루프를 제공했습니다 :

// forEach 
list.forEach(item -> item.setSomeProperty(1)); 
// for loop 
for (int i = 0 ; i < list.size() ; i++) { 
    list.get(i).setSomeProperty(1); 
} 

// forEach 
list.forEach(item -> item.doStuff()); 
// for loop 
for (int i = 0 ; i < list.size() ; i++) { 
    list.get(i).doStuff() 
} 

// forEach 
list.forEach(item -> System.out.println(item)); 
// for loop 
for (int i = 0 ; i < list.size() ; i++) { 
    System.out.println(list.get(i)); 
} 

위의 예제를 보면 구문을 이해할 수 있기를 바랍니다. 마지막 예제가 단순화 될 수있다

참고 :

list.forEach(System.out::println); 

우리는 기본적으로 각 항목에 System.out::println 전화를 말하는 것입니다.