我对Java中的lambda表达式有疑问。
List<String> l = new ArrayList<String>();
l.add("Besit");
l.add("Java");
String str = "Java";
boolean flag = false;
int counter = 0;
l.forEach((h) -> {
if (h.equals(str)) {
counter++;
flag = true.
}
});
很显然,我有错误,因为forEach没有看到str
和flag
,我知道在C ++ lambda中我们可以通过引用传递一些参数。可以在Java中做到吗?
答案 0 :(得分:4)
您应该以不同的方式处理该问题,以便不需要在lambda中更新@RestController
@EnableAutoConfiguration
public class MyController {
@Autowired
private Service1 service;
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/logError", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
public ResponseEntity ErrorHandlor(@RequestBody JSONStructure jsonStructure) throws Exception{
service.getDocument(jsonStructure.getID(), jsonStructure.getLog());
return new ResponseEntity(HttpStatus.OK);
}
}
(尽管您可以访问@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {MyController.class,
Service1.class, AppConfig.class})
@WebMvcTest(MyController.class)
public class MyControllerTest {
private MockMvc mockMvc;
@MockBean
private RestTemplate restTemplate;
MyController service = new MyController();
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(service).build();
}
@Test
public void testController() throws Exception{
ObjectMapper mapper = new ObjectMapper();
String url = "http://localhost:8080/logError";
JSONStructure structure = new JSONStructure();
structure.setNumber("num");
structure.setID("id");
structure.setLog("log");
String json = mapper.writeValueAsString(structure)
this.mockMvc.perform
(MockMvcRequestBuilders.post("http://localhost:8080/logError")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(MockMvcResultMatchers.status().isCreated())
.andReturn();
}
):
flag
对于您的updated code,您可以执行以下操作:
str
答案 1 :(得分:0)
@AndyTurner的答案是正确的,但是我想解释一下为什么您无法在尝试的地方做任何事情。
lambda只能在包含范围内的变量被标记为最终变量(或实际上是最终变量)时才能看到。
您的String str
实际上是最终版本,但是您不能将boolean flag
标记为最终版本,因为您希望自己的Lambda对其进行修改。
解决此问题的一种方法是使用最终的AtomicBoolean
而不是您的boolean flag
。然后,您可以调用AtomicBoolean上的set()
来更改其包含的值。
答案 2 :(得分:0)
不是没有看到str,counter和flag,而是它们必须有效地为final,换句话说,lambda的代码无法更改它们,无论如何这都是正确的,因为它们被传递了按值且String不可修改。您可以使用感兴趣的各种数量的公共字段或getter / setter方法创建另一个对象,将该对象的实例声明为final,然后将其传递给...
public class Stuff {
public String str = "Java";
public int counter = 0;
public boolean flag = false;
}
final Stuff stuff = new Stuff();
l.forEach((h) -> {
if (h.equals(stuff.str)) {
stuff.counter++;
stuff.flag = true.
}
});