Java 如何在方法中考虑几个参数

Java 如何在方法中考虑几个参数,java,file,io,Java,File,Io,我使用visitFile方法实现了自己的SimpleFileVisitor。 如果参数不止一个,我想知道如何执行更精确的搜索。这就是我的意思 public class SearchFileVisitor extends SimpleFileVisitor<Path> { private String partOfName; private String partOfContent; private int minSize; private int ma

我使用visitFile方法实现了自己的SimpleFileVisitor。 如果参数不止一个,我想知道如何执行更精确的搜索。这就是我的意思

public class SearchFileVisitor extends SimpleFileVisitor<Path>
{
    private String partOfName;
    private String partOfContent;
    private int minSize;
    private int maxSize;
    private List<Path> foundFiles = new ArrayList<>();

    public void setPartOfName(String partOfName)
    {
        this.partOfName = partOfName;
    }

    public void setPartOfContent(String partOfContent)
    {
        this.partOfContent = partOfContent;
    }

    public void setMinSize(int minSize)
    {
        this.minSize = minSize;
    }

    public void setMaxSize(int maxSize)
    {
        this.maxSize = maxSize;
    }

    public List<Path> getFoundFiles()
    {
        return foundFiles;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
    {
        if(partOfName != null && file.toString().contains(partOfName))
        {
           foundFiles.add(file);
        }
        else if(partOfContent != null)
            {
                try(Scanner scanner = new Scanner(file))
                {
                    while(scanner.hasNextLine())
                    {
                        String line = scanner.nextLine();
                        if(line.contains(partOfContent))
                        {
                            foundFiles.add(file);
                            break;
                        }
                    }
                }
            }
         else if(file.toFile().length() < maxSize)
         {
             foundFiles.add(file);
         }
         else if(file.toFile().length() > minSize)
         {
             foundFiles.add(file);
         }
        return super.visitFile(file, attrs);
    }
}
公共类SearchFileVisitor扩展了SimpleFileVisitor
{
私有字符串部分名称;
内容的私有字符串部分;
私人机构;
私有int-maxSize;
private List foundFiles=new ArrayList();
公共void setPartOfName(字符串partOfName)
{
this.partOfName=partOfName;
}
public void setPartOfContent(内容的字符串部分)
{
this.partOfContent=部分内容;
}
公共void setMinSize(int minSize)
{
this.minSize=minSize;
}
公共void setMaxSize(int maxSize)
{
this.maxSize=maxSize;
}
公共列表getFoundFiles()
{
归还文件;
}
@凌驾
公共文件VisitResult visitFile(路径文件,基本文件属性属性属性)引发IOException
{
if(partOfName!=null&&file.toString().contains(partOfName))
{
foundFiles.add(文件);
}
else if(partOfContent!=null)
{
尝试(扫描仪=新扫描仪(文件))
{
while(scanner.hasNextLine())
{
字符串行=scanner.nextLine();
if(行包含(部分内容))
{
foundFiles.add(文件);
打破
}
}
}
}
else if(file.toFile().length()minSize)
{
foundFiles.add(文件);
}
返回super.visitFile(文件,attrs);
}
}
主要方法是:

public static void main(String[] args) throws IOException
    {
        SearchFileVisitor searchFileVisitor = new SearchFileVisitor();

        searchFileVisitor.setPartOfName("John");
        searchFileVisitor.setPartOfContent("be or not to be?");
        searchFileVisitor.setMinSize(500);
        searchFileVisitor.setMaxSize(10000);

        Files.walkFileTree(Paths.get("D:/SecretFolder"), searchFileVisitor);

        List<Path> foundFiles = searchFileVisitor.getFoundFiles();
        for (Path file : foundFiles)
        {
            System.out.println(file);
        }
    }
publicstaticvoidmain(字符串[]args)引发IOException
{
SearchFileVisitor SearchFileVisitor=新建SearchFileVisitor();
searchFileVisitor.setPartOfName(“John”);
searchFileVisitor.setPartOfContent(“是或不是?”);
searchFileVisitor.setMinSize(500);
searchFileVisitor.setMaxSize(10000);
Files.walkFileTree(path.get(“D:/SecretFolder”)、searchFileVisitor);
List foundFiles=searchFileVisitor.getFoundFiles();
用于(路径文件:foundFiles)
{
System.out.println(文件);
}
}

所以,若我只设置了名称的一部分,那个么它应该只传递给它。但若在它旁边我也设置了部分内容,并说maxSize,那个么到目前为止,它应该同时传递3个参数。因此,如果有4个PAR,它应该在四上中继并添加到列表中,如果该对象满足所有标准。我该怎么做?(没有该死的布尔标志)

注意,这只是描述了一般的想法。回顾一下,我可能会重新考虑类名和方法名

我将引入一个“谓词”,并使用decorator以声明的方式描述预期结果

谓词的接口如下所示:

public interface Predicate {
    boolean matches (Path file, BasicFileAttributes attrs);
}
SearchFileVisitor searchFileVisitor =
    new SearchFileVisitor(
        new MaxSized(10000,
            new Named("John",
                new All())));
每个实例仅匹配一个条件,如名称,并委托另一个谓词进行其他测试:

public final class Named implements Predicate{

   private final Predicate mDelegate;
   private final String mPartOfName;

   public Named(String partOfName, Predicate delegate)
   {
       mPartOfName = partOfName;
       mDelegate = delegate;
   }

   @Override
   public boolean matches(Path file, BasicFileAttributes attrs)
   {
       return file.toString().contains(mPartOfName) && mDelegate.matches(file, attrs);
   }
}
或最大尺寸:

public final class MaxSized implements Predicate{

   private final Predicate mDelegate;
   private final int mMaxSize;

   public MaxSized(int maxSize, Predicate delegate)
   {
       mMaxSize = maxSize;
       mDelegate = delegate;
   }

   @Override
   public boolean matches(Path file, BasicFileAttributes attrs)
   {
       return file.toFile().length() < mMaxSize && mDelegate(file, attrs);
   }
}
SeachFileVisitor
将缩减为以下内容:

public final class SearchFileVisitor extends SimpleFileVisitor<Path>{
    private final List<Path> foundFiles = new ArrayList<>();
    private final Predicate mPredicate;

    public SearchFileVisitor(Predicate predicate){
        mPredicate = predicate;
    }


    public List<Path> getFoundFiles() {
        return foundFiles;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        if (mPredicate.matches(file, attrs)) {
            foundFiles.add(file);
        }
    }
}
谓词可以理解为“return
所有
命名的
元素,如
“John”
,最大大小为
10000
”。您也可以这样向前阅读:“一个大小受限和名称受限的match-all谓词版本”

  • 谓词是不可变的,因此在并发环境中没有副作用
  • 所有的课程都很短,简单,易于测试
  • 可以在不修改现有代码的情况下添加新谓词
  • 没有“该死的布尔标志”

对于每个参数,应将逻辑结构为“参数被禁用或文件通过参数检查”

首先,使用默认值指示参数已禁用:

private String partOfName = null;
private String partOfContent = null;
private int minSize = -1;
private int maxSize = -1;
然后,您可以使用单个if语句,并在单独的方法中使用partOfContent check来保持简单:

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
    if ((partOfName == null || file.toString().contains(partOfName))
            && (partOfContent == null || fileContains(file, partOfContent))
            && (maxSize < 0 || file.toFile().length() < maxSize)
            && (minSize < 0 || file.toFile().length() > minSize)) {
        foundFiles.add(file);
    }
    return super.visitFile(file, attrs);
}

private static boolean fileContains(Path file, String partOfContent) throws IOException {
    try (Scanner scanner = new Scanner(file)) {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            if (line.contains(partOfContent)) {
                return true;
            }
        }
    }
    return false;
}
@覆盖
公共文件VisitResult visitFile(路径文件,基本文件属性属性属性)引发IOException{
if((partOfName==null | | file.toString().contains(partOfName))
&&(partOfContent==null | | fileContains(文件,partOfContent))
&&(maxSize<0 | | file.toFile().length()minSize)){
foundFiles.add(文件);
}
返回super.visitFile(文件,attrs);
}
私有静态布尔文件包含(路径文件,内容的字符串部分)引发IOException{
尝试(扫描仪=新扫描仪(文件)){
while(scanner.hasNextLine()){
字符串行=scanner.nextLine();
if(行包含(部分内容)){
返回true;
}
}
}
返回false;
}
您应该使用流,而不是像这样使用FileVisitor

static boolean contains(Path path, String partOfContent) {
    try (Scanner scanner = new Scanner(path)) {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            if (line.contains(partOfContent)) {
                return true;
            }
        }
    } catch (IOException e) {
        return false;
    }
    return false;
}

public static void main(String[] args) throws IOException {
    List<Path> results = Files.walk(Paths.get("D:/SecretFolder"))
        .filter(path -> Files.isRegularFile(path))
        .filter(path -> path.toString().contains("Jhon"))
        .filter(path -> contains(path, "be or not to be?"))
        .filter(path -> path.toFile().length() >= 500)
        .filter(path -> path.toFile().length() <= 10000)
        .collect(Collectors.toList());
    results.stream()
        .forEach(System.out::println);
}
静态布尔包含(路径,内容的字符串部分){
尝试(扫描仪=新扫描仪(路径)){
while(scanner.hasNextLine()){
字符串行=scanner.nextLine();
if(行包含(部分内容)){
返回true;
}
}
}捕获(IOE异常){
返回false;
}
返回false;
}
公共静态void main(字符串[]args)引发IOException{
列表结果=Files.walk(path.get(“D:/SecretFolder”))
.filter(路径->文件.isRegularFile(路径))
.filter(path->path.toString().contains(“Jhon”))
.filter(路径->包含(路径“是否存在?”)
.filter(路径->路径.toFile().length()>=500)

.filter(path->path.toFile().length()有不同的方法,其中之一是拆分类
SearchFileVisitorstatic boolean contains(Path path, String partOfContent) {
    try (Scanner scanner = new Scanner(path)) {
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            if (line.contains(partOfContent)) {
                return true;
            }
        }
    } catch (IOException e) {
        return false;
    }
    return false;
}

public static void main(String[] args) throws IOException {
    List<Path> results = Files.walk(Paths.get("D:/SecretFolder"))
        .filter(path -> Files.isRegularFile(path))
        .filter(path -> path.toString().contains("Jhon"))
        .filter(path -> contains(path, "be or not to be?"))
        .filter(path -> path.toFile().length() >= 500)
        .filter(path -> path.toFile().length() <= 10000)
        .collect(Collectors.toList());
    results.stream()
        .forEach(System.out::println);
}