有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java查找数组(如果它是另一个数组的子集)

仅当参数对象是调用对象的子集时,此函数才应返回true,但它始终返回true。如何修复它

    public boolean contains(FileCollection other) {
        int i = 0;
        int j = 0;
        for (i = 0; i<other.files.length; i++) {
            for (j = 0; j<this.files.length; j++) {
                if ((other.files[i]).equals((this.files[j]))) //this refers to the equals method defined in File class
                    break;
            }
            if (j==this.files.length) 
                return false;
        }
        return true;//this method is in FileCollection class
    }

共 (3) 个答案

  1. # 1 楼答案

    除了@renyuneyun建议将数组转换为列表之外,还可以使用Stringcontains方法

    public boolean contains(FileCollection other) {
    String myList = Arrays.toString(this.files);
    String otherList = Arrays.toString(other.files);
    return myList.contains(otherList);
    }
    

    当然,从复杂性的角度来看,这两个建议都不是最佳解决方案,但肯定是最短的:)

  2. # 2 楼答案

    (因为您没有明确表示数组元素的数据类型,所以我假设它是File,由注释推断出来的。)

    如果您不介意在数据结构之间转换,也许将数组(暂时)转换为集合是最简单的方法。例如,转换为List

    /* @param other
     * @return true if the calling object contains
     * all files in the parameter object, false otherwise
     */
    public boolean contains(FileCollection other) {
        List<File> myList = Arrays.asList(this.files);
        List<File> otherList = Arrays.asList(other.files);
        return myList.containsAll(otherList);
    }
    

    根据您对允许重复项目时“包含”内容的澄清,我认为您需要计算每个元素的存在数量。以下是方法:

    根据@Eritrean的答案,你可以获得并将计数存储到地图上。我也做了一些修改来检查计数:

    public boolean contains(FileCollection other) {
        Map<File,Integer> otherFrequency = Arrays.stream(other.files)
                .collect(Collectors.toMap(Function.identity(), v->1,Integer::sum));
    
        Map<File,Integer> thisFrequency  = Arrays.stream(this.files) 
                .collect(Collectors.toMap(Function.identity(), v->1,Integer::sum));
    
        if (thisFrequency.entrySet().containsAll(otherFrequency).entrySet()) {
            for (File entry : otherFrequency.entrySet()) {
                if (thisFrequency.get(entry) < otherFrequency.get(entry))
                    return false;
            }
            return true;
        }
        return false;
    }
    
  3. # 3 楼答案

    只有这个答案对我有效:(比较部分归功于@Joop Eggen)

    public boolean contains(FileCollection other) {
        Comparator<File> comparator = new Comparator<File>() {
            @Override
            public int compare(File lhs, File rhs) {
                int cmp = lhs.getBase().compareToIgnoreCase(rhs.getBase());
                if (cmp == 0) {
                   cmp = lhs.getExtension().compareToIgnoreCase(rhs.getExtension());
                }
                if (cmp == 0) {
                   cmp = Long.compare(lhs.getSize(), rhs.getSize());
                }
                if (cmp == 0) {
                   cmp = Long.compare(lhs.getPermissions(), rhs.getPermissions());
                }
                return cmp;
            }
        };
        Arrays.sort(this.files, comparator);
        Arrays.sort(other.files, comparator); //THIS AND THE COMPARATOR SORT THE ARRAYS BASED ON ALL FILE ATTRIBUTES    
        int i = 0;
        int j = 0;
        if (this.files.length<other.files.length)
            return false;
        while (i<other.files.length && j<this.files.length) {
            if (!(this.files[j].equals(other.files[i])))
                j++;
            else {
                j++;
                i++;
            }
        }
        if (i<other.files.length)
            return false;
        else
            return true; 
    }