IDEA-161861 Stream API migration should handle cases where result variable is not declared just before the for loop

This commit is contained in:
Tagir Valeev
2016-09-29 15:54:08 +07:00
parent b962a9f417
commit b9a06d65b9
57 changed files with 681 additions and 68 deletions
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -72,14 +73,13 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
PsiType expressionType) {
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
restoreComments(foreachStatement, foreachStatement.getBody());
if (StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) {
InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement);
if (status != InitializerUsageStatus.UNKNOWN) {
PsiExpression initializer = var.getInitializer();
if (ExpressionUtils.isZero(initializer)) {
PsiType type = var.getType();
String replacement = (type.equals(expressionType) ? "" : "(" + type.getCanonicalText() + ") ") + builder;
initializer.replace(elementFactory.createExpressionFromText(replacement, foreachStatement));
removeLoop(foreachStatement);
simplifyAndFormat(project, var);
replaceInitializer(foreachStatement, var, initializer, replacement, status);
return;
}
}
@@ -88,6 +88,27 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
simplifyAndFormat(project, result);
}
static void replaceInitializer(PsiForeachStatement foreachStatement,
PsiVariable var,
PsiExpression initializer,
String replacement,
InitializerUsageStatus status) {
Project project = foreachStatement.getProject();
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
if(status == InitializerUsageStatus.DECLARED_JUST_BEFORE) {
initializer.replace(elementFactory.createExpressionFromText(replacement, foreachStatement));
removeLoop(foreachStatement);
simplifyAndFormat(project, var);
} else {
if(status == InitializerUsageStatus.AT_WANTED_PLACE_ONLY) {
initializer.delete();
}
PsiElement result =
foreachStatement.replace(elementFactory.createStatementFromText(var.getName() + " = " + replacement + ";", foreachStatement));
simplifyAndFormat(project, result);
}
}
static void simplifyAndFormat(@NotNull Project project, PsiElement result) {
if (result == null) return;
LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result);
@@ -16,7 +16,9 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -32,6 +34,8 @@ import java.util.List;
* @author Tagir Valeev
*/
class ReplaceWithCollectFix extends MigrateToStreamFix {
private static final Logger LOG = Logger.getInstance(ReplaceWithCollectFix.class);
final String myMethodName;
protected ReplaceWithCollectFix(String methodName) {
@@ -87,16 +91,18 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
final StringBuilder builder = generateStream(iteratedValue, operations);
final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
final PsiExpression initializer = StreamApiMigrationInspection
.extractReplaceableCollectionInitializer(qualifierExpression, foreachStatement);
if (initializer != null) {
String callText = builder.append(".collect(java.util.stream.Collectors.")
.append(createInitializerReplacementText(qualifierExpression.getType(), initializer))
.append(")").toString();
PsiElement result = initializer.replace(elementFactory.createExpressionFromText(callText, null));
simplifyAndFormat(project, result);
removeLoop(foreachStatement);
return;
final PsiLocalVariable variable = StreamApiMigrationInspection.extractCollectionVariable(qualifierExpression);
if (variable != null) {
InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(variable, foreachStatement);
if(status != InitializerUsageStatus.UNKNOWN) {
PsiExpression initializer = variable.getInitializer();
LOG.assertTrue(initializer != null);
String callText = builder.append(".collect(java.util.stream.Collectors.")
.append(createInitializerReplacementText(qualifierExpression.getType(), initializer))
.append(")").toString();
replaceInitializer(foreachStatement, variable, initializer, callText, status);
return;
}
}
final String qualifierText = qualifierExpression != null ? qualifierExpression.getText() + "." : "";
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -76,13 +77,12 @@ class ReplaceWithFindFirstFix extends MigrateToStreamFix {
PsiExpression value = assignment.getRExpression();
if (value == null) return;
restoreComments(foreachStatement, body);
if (StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) {
InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement);
if (status != InitializerUsageStatus.UNKNOWN) {
PsiExpression initializer = var.getInitializer();
if (initializer != null) {
PsiElement result =
initializer.replace(elementFactory.createExpressionFromText(generateOptionalUnwrap(stream, tb, value, initializer), initializer));
removeLoop(foreachStatement);
simplifyAndFormat(project, result);
String replacementText = generateOptionalUnwrap(stream, tb, value, initializer);
replaceInitializer(foreachStatement, var, initializer, replacementText, status);
return;
}
}
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -93,7 +94,8 @@ class ReplaceWithMatchFix extends MigrateToStreamFix {
// for(....) if(...) {flag = true; break;}
PsiVariable var = (PsiVariable)maybeVar;
PsiExpression initializer = var.getInitializer();
if(initializer != null && StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) {
InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement);
if(initializer != null && status != InitializerUsageStatus.UNKNOWN) {
String replacement;
if(ExpressionUtils.isLiteral(initializer, Boolean.FALSE) &&
ExpressionUtils.isLiteral(rValue, Boolean.TRUE)) {
@@ -104,9 +106,7 @@ class ReplaceWithMatchFix extends MigrateToStreamFix {
} else {
replacement = streamText + "?" + rValue.getText() + ":" + initializer.getText();
}
PsiElement result = initializer.replace(elementFactory.createExpressionFromText(replacement, initializer));
removeLoop(foreachStatement);
simplifyAndFormat(project, result);
replaceInitializer(foreachStatement, var, initializer, replacement, status);
return;
}
}
@@ -49,6 +49,8 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.*;
import static com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus.*;
/**
* User: anna
*/
@@ -377,19 +379,17 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
return consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, variable.getType()) : null;
}
@Contract("null, _ -> null")
static PsiExpression extractReplaceableCollectionInitializer(PsiExpression qualifierExpression, PsiStatement foreachStatement) {
@Contract("null -> null")
static PsiLocalVariable extractCollectionVariable(PsiExpression qualifierExpression) {
if (qualifierExpression instanceof PsiReferenceExpression) {
final PsiElement resolve = ((PsiReferenceExpression)qualifierExpression).resolve();
if (resolve instanceof PsiLocalVariable) {
PsiLocalVariable var = (PsiLocalVariable)resolve;
if (isDeclarationJustBefore(var, foreachStatement)) {
final PsiExpression initializer = var.getInitializer();
if (initializer instanceof PsiNewExpression) {
final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList();
if (argumentList != null && argumentList.getExpressions().length == 0) {
return initializer;
}
final PsiExpression initializer = var.getInitializer();
if (initializer instanceof PsiNewExpression) {
final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList();
if (argumentList != null && argumentList.getExpressions().length == 0) {
return var;
}
}
}
@@ -397,6 +397,40 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
return null;
}
enum InitializerUsageStatus {
// Variable is declared just before the wanted place
DECLARED_JUST_BEFORE,
// All initial value usages go through wanted place and at wanted place the variable value is guaranteed to be the initial value
AT_WANTED_PLACE_ONLY,
// At wanted place the variable value is guaranteed to be the initial value, but this initial value might be used somewhere else
AT_WANTED_PLACE,
// It's not guaranteed that the variable value at wanted place is initial value
UNKNOWN
}
static InitializerUsageStatus getInitializerUsageStatus(PsiVariable var, PsiStatement nextStatement) {
if(var.getInitializer() == null) return UNKNOWN;
if(isDeclarationJustBefore(var, nextStatement)) return DECLARED_JUST_BEFORE;
PsiElement declaration = var.getParent();
// Check if variable is not referenced in the same declaration like "int a = 0, b = a;"
if(!PsiTreeUtil.processElements(declaration, e -> !(e instanceof PsiReferenceExpression) ||
((PsiReferenceExpression)e).resolve() != var)) return UNKNOWN;
PsiElement block = PsiUtil.getVariableCodeBlock(var, null);
if(block == null) return UNKNOWN;
final ControlFlow controlFlow;
try {
controlFlow = ControlFlowFactory.getInstance(nextStatement.getProject())
.getControlFlow(block, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance());
}
catch (AnalysisCanceledException ignored) {
return UNKNOWN;
}
int start = controlFlow.getEndOffset(declaration);
int stop = controlFlow.getStartOffset(nextStatement);
if(ControlFlowUtil.isVariableReferencedBetween(controlFlow, start, stop, var)) return UNKNOWN;
return ControlFlowUtil.isValueUsedWithoutVisitingStop(controlFlow, start, stop, var) ? AT_WANTED_PLACE : AT_WANTED_PLACE_ONLY;
}
static boolean isDeclarationJustBefore(PsiVariable var, PsiStatement nextStatement) {
PsiElement declaration = var.getParent();
PsiElement nextStatementParent = nextStatement.getParent();
@@ -482,8 +516,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
methodName = "addAll";
} else {
PsiMethodCallExpression methodCallExpression = tb.getSingleMethodCall();
if(methodCallExpression != null && extractReplaceableCollectionInitializer(
methodCallExpression.getMethodExpression().getQualifierExpression(), statement) != null) {
if(canCollect(statement, methodCallExpression)) {
methodName = "collect";
} else {
if (!SUGGEST_FOREACH) return;
@@ -535,13 +568,19 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
}
void handleSingleReturn(PsiForeachStatement statement,
TerminalBlock tb,
List<Operation> operations) {
boolean canCollect(PsiForeachStatement statement, PsiMethodCallExpression methodCallExpression) {
if(methodCallExpression == null) return false;
PsiLocalVariable variable = extractCollectionVariable(methodCallExpression.getMethodExpression().getQualifierExpression());
if(variable == null) return false;
return getInitializerUsageStatus(variable, statement) != UNKNOWN;
}
void handleSingleReturn(PsiForeachStatement statement, TerminalBlock tb, List<Operation> operations) {
PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement();
PsiExpression value = returnStatement.getReturnValue();
PsiReturnStatement nextReturnStatement = getNextReturnStatement(statement);
if(nextReturnStatement != null && (ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE))) {
if (nextReturnStatement != null &&
(ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE))) {
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
if(ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
String methodName;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ import com.intellij.util.containers.IntArrayList;
import com.intellij.util.containers.IntStack;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TIntArrayList;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -1284,6 +1285,112 @@ public class ControlFlowUtil {
return visitor.getResult().booleanValue();
}
/**
* Returns true if the value the variable has at start is later referenced without going through stop instruction
*
* @param flow ControlFlow to analyze
* @param start the point at which variable value is created
* @param stop the stop-point
* @param variable the variable to examine
* @return true if the value the variable has at start is later referenced without going through stop instruction
*/
public static boolean isValueUsedWithoutVisitingStop(final ControlFlow flow, final int start, final int stop, final PsiVariable variable) {
if(start == stop) return false;
class MyVisitor extends InstructionClientVisitor<Boolean> {
// true if value the variable has at given offset maybe referenced without going through stop instruction
final boolean[] maybeReferenced = new boolean[flow.getSize() + 1];
@Override
public void visitInstruction(Instruction instruction, int offset, int nextOffset) {
if (offset == stop) {
maybeReferenced[offset] = false;
return;
}
if(instruction instanceof WriteVariableInstruction && ((WriteVariableInstruction)instruction).variable == variable) {
maybeReferenced[offset] = false;
return;
}
if (maybeReferenced[offset]) return;
if (nextOffset > flow.getSize()) nextOffset = flow.getSize();
boolean nextState = maybeReferenced[nextOffset];
maybeReferenced[offset] =
nextState || (instruction instanceof ReadVariableInstruction && ((ReadVariableInstruction)instruction).variable == variable);
}
@Override
public Boolean getResult() {
return maybeReferenced[start];
}
}
MyVisitor visitor = new MyVisitor();
depthFirstSearch(flow, visitor, start, flow.getSize());
return visitor.getResult().booleanValue();
}
/**
* Checks whether variable can be referenced between start and stop points. Back-edges are also considered, so the actual place
* where it referenced might be outside of (start, stop) interval.
*
* @param flow ControlFlow to analyze
* @param start start point
* @param stop stop point
* @param variable variable to analyze
* @return true if variable can be referenced between start and stop points
*/
public static boolean isVariableReferencedBetween(final ControlFlow flow,
final int start,
final int stop,
final PsiVariable variable) {
if(start == stop) return false;
// DFS visits instructions mainly in backward direction while here visiting in forward direction
// greatly reduces number of iterations. So first we just collect edges, then reverse their order.
// contains (from, to) pairs representing control flow arcs
final TIntArrayList list = new TIntArrayList();
depthFirstSearch(flow, new InstructionClientVisitor<Void>() {
@Override
public void visitInstruction(Instruction instruction, int offset, int nextOffset) {
list.add(offset);
list.add(nextOffset);
}
@Override
public Void getResult() {
return null;
}
}, start, flow.getSize());
BitSet violated = new BitSet();
List<Instruction> instructions = flow.getInstructions();
boolean changed = true;
while(changed) {
changed = false;
for(int i=list.size()-2; i>=0; i-=2) {
int from = list.get(i);
int to = list.get(i+1);
if(from == stop) continue;
if(violated.get(from)) {
if(!violated.get(to)) {
if(to == stop) return true;
violated.set(to);
changed = true;
}
continue;
}
Instruction instruction = instructions.get(from);
if((instruction instanceof ReadVariableInstruction && ((ReadVariableInstruction)instruction).variable == variable) ||
(instruction instanceof WriteVariableInstruction && ((WriteVariableInstruction)instruction).variable == variable)) {
violated.set(from);
violated.set(to);
if(to == stop) return true;
changed = true;
}
}
}
return false;
}
/**
* @return min offset after sourceOffset which is definitely reachable from all references
*/
@@ -4,6 +4,6 @@ import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
String found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()) ? "yes" : "no";
String found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()) ? "yes" : "no";
}
}
@@ -4,6 +4,6 @@ import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
boolean found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
}
}
@@ -4,6 +4,6 @@ import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = !data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
boolean found = !data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
}
}
@@ -0,0 +1,14 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found;
if (data.size() > 10) {
System.out.println("Big data");
}
found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
System.out.println(found);
}
}
@@ -4,13 +4,12 @@ import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = false;
boolean found;
if(Math.random() > 0.5) {
found = true;
} else {
if (data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty())) {
found = true;
}
found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
}
System.out.println(found);
}
}
@@ -0,0 +1,15 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = false;
if(Math.random() > 0.5) {
System.out.println("oops");
} else {
found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
}
System.out.println(found);
}
}
@@ -0,0 +1,16 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found;
try {
found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
System.out.println(found);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
@@ -0,0 +1,16 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = false;
try {
found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
}
catch(Exception ex) {
ex.printStackTrace();
}
System.out.println(found);
}
}
@@ -6,6 +6,6 @@ import java.util.stream.Collectors;
public class Main {
public void test(Integer[] arr) {
List<Integer> result = Arrays.stream(arr).filter(x -> x > 5).collect(Collectors.toList());
List<Integer> result = Arrays.stream(arr).filter(x -> x > 5).collect(Collectors.toList());
}
}
@@ -4,7 +4,7 @@ import java.util.stream.Collectors;
class A {
public static void main(List<String> args) {
ArrayList<String> uniqNames = args.stream().map(name -> name.substring(1)).collect(Collectors.toCollection(ArrayList::new));
ArrayList<String> uniqNames = args.stream().map(name -> name.substring(1)).collect(Collectors.toCollection(ArrayList::new));
uniqNames.forEach(System.out::println);
}
@@ -5,7 +5,7 @@ import java.util.stream.Collectors;
class Test {
public static <T> List<TokenFilter<T>> fromString(final T src, Function<T, List<String>> extractor) {
final List<TokenFilter<T>> result = extractor.apply(src).stream().map((Function<String, TokenFilter<T>>) TokenFilter::new).collect(Collectors.toList());
final List<TokenFilter<T>> result = extractor.apply(src).stream().map((Function<String, TokenFilter<T>>) TokenFilter::new).collect(Collectors.toList());
return result;
}
@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
}
}
@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
List<String> names = persons.stream().filter(Objects::nonNull).map(Person::getName).collect(Collectors.toList());
List<String> names = persons.stream().filter(Objects::nonNull).map(Person::getName).collect(Collectors.toList());
}
}
@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
Collection<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
Collection<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
}
}
@@ -10,7 +10,7 @@ public class Collect {
}
void collectNames(List<Person> persons){
List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
//some comment
}
}
@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
List<String> names = persons.stream().map(person -> "name: " + person.getName()).collect(Collectors.toList());
List<String> names = persons.stream().map(person -> "name: " + person.getName()).collect(Collectors.toList());
}
}
@@ -6,6 +6,6 @@ import java.util.stream.Collectors;
public class Main {
public void testPrimitiveMap(List<String> data) {
List<Integer> list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).boxed().collect(Collectors.toList());
List<Integer> list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).boxed().collect(Collectors.toList());
}
}
@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toSet());
Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toSet());
}
}
@@ -0,0 +1,17 @@
// "Replace with collect" "true"
import java.util.*;
import java.util.stream.Collectors;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
Set<String> names, other = new HashSet<>();
names = persons.stream().map(Person::getName).collect(Collectors.toSet());
System.out.println(names);
}
}
@@ -0,0 +1,18 @@
// "Replace with forEach" "true"
import java.util.*;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
Set<String> names = new HashSet<>();
for(int i=0; i<10; i++) {
persons.stream().map(Person::getName).forEach(names::add);
}
System.out.println(names);
}
}
@@ -0,0 +1,17 @@
// "Replace with forEach" "true"
import java.util.*;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
Set<String> names = new HashSet<>();
names.add("Test");
persons.stream().map(Person::getName).forEach(names::add);
System.out.println(names);
}
}
@@ -0,0 +1,19 @@
// "Replace with collect" "true"
import java.util.*;
import java.util.stream.Collectors;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
Set<String> names = new HashSet<>(), other = new HashSet<>();
if(persons != null) {
names = persons.stream().map(Person::getName).collect(Collectors.toSet());
}
System.out.println(names);
}
}
@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toCollection(LinkedHashSet::new));
Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toCollection(LinkedHashSet::new));
}
}
@@ -6,6 +6,6 @@ import java.util.stream.Collectors;
public class Main {
public void testPrimitiveMap(List<String> data) {
List<String> list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).mapToObj(String::valueOf).collect(Collectors.toList());
List<String> list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).mapToObj(String::valueOf).collect(Collectors.toList());
}
}
@@ -6,7 +6,7 @@ import java.util.stream.Collectors;
public class Main {
public List<String> test(Map<String, List<String>> map) {
List<String> result = map.entrySet().stream().filter(entry -> !entry.getKey().isEmpty()).map(Map.Entry::getValue).filter(Objects::nonNull).flatMap(Collection::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList());
List<String> result = map.entrySet().stream().filter(entry -> !entry.getKey().isEmpty()).map(Map.Entry::getValue).filter(Objects::nonNull).flatMap(Collection::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList());
return result;
}
}
@@ -6,7 +6,7 @@ import java.util.stream.Collectors;
public class Main {
public List<String> test(Map<String, List<String>> map) {
List<String> result = map.entrySet().stream().filter(entry -> !entry.getKey().isEmpty()).map(Map.Entry::getValue).filter(Objects::nonNull).flatMap(Collection::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList());
List<String> result = map.entrySet().stream().filter(entry -> !entry.getKey().isEmpty()).map(Map.Entry::getValue).filter(Objects::nonNull).flatMap(Collection::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList());
return result;
}
}
@@ -4,6 +4,6 @@ import java.util.stream.Collectors;
public class Main {
public void test(List<Set<String>> nested) {
List<String> result = nested.stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> str.startsWith("xyz")).map(String::trim).collect(Collectors.toList());
List<String> result = nested.stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> str.startsWith("xyz")).map(String::trim).collect(Collectors.toList());
}
}
@@ -6,6 +6,6 @@ import java.util.stream.Collectors;
public class Main {
public void test(List<String[]> list) {
List<String> result = list.stream().filter(arr -> arr.length > 2).flatMap(Arrays::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList());
List<String> result = list.stream().filter(arr -> arr.length > 2).flatMap(Arrays::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList());
}
}
@@ -7,6 +7,6 @@ import java.util.stream.Collectors;
public class Main {
public void test(Map<String, String[]> map) {
List<String> result = map.entrySet().stream().filter(entry -> entry.getKey().startsWith("x")).map(Map.Entry::getValue).flatMap(Arrays::stream).map(String::trim).collect(Collectors.toList());
List<String> result = map.entrySet().stream().filter(entry -> entry.getKey().startsWith("x")).map(Map.Entry::getValue).flatMap(Arrays::stream).map(String::trim).collect(Collectors.toList());
}
}
@@ -6,7 +6,7 @@ import java.util.Objects;
public class Main {
public void testMap(Map<String, List<String>> map) throws Exception {
int firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(0);
int firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(0);
// comment
System.out.println(firstSize);
}
@@ -4,7 +4,7 @@ import java.util.List;
public class Main {
public void testCast(List<Object> data) {
String found = (String) data.stream().filter(obj -> obj instanceof String).findFirst().orElse(null);
String found = (String) data.stream().filter(obj -> obj instanceof String).findFirst().orElse(null);
System.out.println(found);
}
}
@@ -0,0 +1,18 @@
// "Replace with findFirst()" "true"
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Main {
public void testMap(Map<String, List<String>> map) throws Exception {
int firstSize;
int other = map.size();
if(other > 10) {
System.out.println("Big");
}
// comment
firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(0);
System.out.println(firstSize);
}
}
@@ -0,0 +1,14 @@
// "Replace with findFirst()" "true"
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Main {
public void testMap(Map<String, List<String>> map) throws Exception {
int firstSize = 0, other = firstSize;
// comment
firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(firstSize);
System.out.println(firstSize);
}
}
@@ -7,7 +7,7 @@ import java.util.Objects;
public class Main {
public void testMap(Map<String, List<String>> map) throws Exception {
String firstStr = map.values().stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> !str.isEmpty()).findFirst().orElse("");
String firstStr = map.values().stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> !str.isEmpty()).findFirst().orElse("");
System.out.println(firstStr);
}
}
@@ -7,7 +7,7 @@ import java.util.stream.Collectors;
public class Main {
public List<String> test(String[][] arr) {
List<String> result = Arrays.stream(arr).filter(Objects::nonNull).flatMap(Arrays::stream).collect(Collectors.toList());
List<String> result = Arrays.stream(arr).filter(Objects::nonNull).flatMap(Arrays::stream).collect(Collectors.toList());
return result;
}
}
@@ -7,7 +7,7 @@ import java.util.stream.Collectors;
public class Main {
public List<Integer> test(int[][] arr) {
List<Integer> result = Arrays.stream(arr).filter(Objects::nonNull).flatMapToInt(Arrays::stream).boxed().collect(Collectors.toList());
List<Integer> result = Arrays.stream(arr).filter(Objects::nonNull).flatMapToInt(Arrays::stream).boxed().collect(Collectors.toList());
return result;
}
}
@@ -0,0 +1,15 @@
// "Replace with sum()" "true"
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
int sum;
if(Math.random() > 0.5) {
sum = 10;
} else {
sum = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).map(len -> len * 2).sum();
}
System.out.println(sum);
}
}
@@ -0,0 +1,15 @@
// "Replace with sum()" "true"
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
int sum = 0;
if(Math.random() > 0.5) {
System.out.println("oops");
} else {
sum = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).map(len -> len * 2).sum();
}
System.out.println(sum);
}
}
@@ -0,0 +1,20 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = false;
if (data.size() > 10) {
System.out.println("Big data");
}
for(String str : da<caret>ta) {
String trimmed = str.trim();
if(!trimmed.isEmpty()) {
found = true;
break;
}
}
System.out.println(found);
}
}
@@ -16,5 +16,6 @@ public class Main {
}
}
}
System.out.println(found);
}
}
@@ -0,0 +1,21 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = false;
if(Math.random() > 0.5) {
System.out.println("oops");
} else {
for (String str : da<caret>ta) {
String trimmed = str.trim();
if (!trimmed.isEmpty()) {
found = true;
break;
}
}
}
System.out.println(found);
}
}
@@ -0,0 +1,22 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = false;
try {
for (String str : da<caret>ta) {
String trimmed = str.trim();
if (!trimmed.isEmpty()) {
found = true;
break;
}
}
System.out.println(found);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
@@ -0,0 +1,22 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public void testAssignment(List<String> data) {
boolean found = false;
try {
for (String str : da<caret>ta) {
String trimmed = str.trim();
if (!trimmed.isEmpty()) {
found = true;
break;
}
}
}
catch(Exception ex) {
ex.printStackTrace();
}
System.out.println(found);
}
}
@@ -0,0 +1,18 @@
// "Replace with collect" "true"
import java.util.*;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
Set<String> names = new HashSet<>(), other = new HashSet<>();
for (Person person : pers<caret>ons) {
names.add(person.getName());
}
System.out.println(names);
}
}
@@ -0,0 +1,20 @@
// "Replace with forEach" "true"
import java.util.*;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
Set<String> names = new HashSet<>();
for(int i=0; i<10; i++) {
for (Person person : pers<caret>ons) {
names.add(person.getName());
}
}
System.out.println(names);
}
}
@@ -0,0 +1,19 @@
// "Replace with forEach" "true"
import java.util.*;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
Set<String> names = new HashSet<>();
names.add("Test");
for (Person person : pers<caret>ons) {
names.add(person.getName());
}
System.out.println(names);
}
}
@@ -0,0 +1,20 @@
// "Replace with collect" "true"
import java.util.*;
public class Collect {
class Person {
String getName() {
return "";
}
}
void collectNames(List<Person> persons){
Set<String> names = new HashSet<>(), other = new HashSet<>();
if(persons != null) {
for (Person person : pers<caret>ons) {
names.add(person.getName());
}
}
System.out.println(names);
}
}
@@ -0,0 +1,22 @@
// "Replace with findFirst()" "true"
import java.util.List;
import java.util.Map;
public class Main {
public void testMap(Map<String, List<String>> map) throws Exception {
int firstSize = 0;
int other = map.size();
if(other > 10) {
System.out.println("Big");
}
for(List<String> list : map.valu<caret>es()) {
if(list != null) {
firstSize = list.size();
// comment
break;
}
}
System.out.println(firstSize);
}
}
@@ -0,0 +1,18 @@
// "Replace with findFirst()" "true"
import java.util.List;
import java.util.Map;
public class Main {
public void testMap(Map<String, List<String>> map) throws Exception {
int firstSize = 0, other = firstSize;
for(List<String> list : map.valu<caret>es()) {
if(list != null) {
firstSize = list.size();
// comment
break;
}
}
System.out.println(firstSize);
}
}
@@ -0,0 +1,22 @@
// "Replace with sum()" "true"
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
int sum = 0;
if(Math.random() > 0.5) {
sum = 10;
} else {
for (String str : dat<caret>a) {
if (str.startsWith("xyz")) {
int len = str.length();
if (len > 10) {
sum += len * 2;
}
}
}
}
System.out.println(sum);
}
}
@@ -0,0 +1,22 @@
// "Replace with sum()" "true"
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
int sum = 0;
if(Math.random() > 0.5) {
System.out.println("oops");
} else {
for (String str : dat<caret>a) {
if (str.startsWith("xyz")) {
int len = str.length();
if (len > 10) {
sum += len * 2;
}
}
}
}
System.out.println(sum);
}
}