Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用于比较CSV文件中的行。使用哪种数据结构最好_Java_Csv - Fatal编程技术网

Java 用于比较CSV文件中的行。使用哪种数据结构最好

Java 用于比较CSV文件中的行。使用哪种数据结构最好,java,csv,Java,Csv,以下是我的csv文件的一些记录 Server1, Database, Oracle, 5.5 Server2, Database, Oracle, 6.2 Server3, OS, Ubuntu, 10.04 Server1, OS, Ubuntu, 10.04 Server2, OS, Ubuntu, 12.04 Server3, Language, Jav, 2.6.3 此文件表示Server1安装了Oracle的5.5版,Server2安装了6.2版,Server3安装了Ubuntu的1

以下是我的csv文件的一些记录

Server1, Database, Oracle, 5.5
Server2, Database, Oracle, 6.2
Server3, OS, Ubuntu, 10.04
Server1, OS, Ubuntu, 10.04
Server2, OS, Ubuntu, 12.04
Server3, Language, Jav, 2.6.3
此文件表示Server1安装了Oracle的5.5版,Server2安装了6.2版,Server3安装了Ubuntu的10.04版

需要找出至少2台不同服务器上安装了过期版本(即不是最新版本的版本)的软件包名称列表。因此,在这种情况下,程序的输出:

Ubuntu
我尝试解析上面的csv文件ArrayList,但发现很难处理问题的进一步逻辑


有人能建议在上述问题中使用的最佳数据结构是什么吗?另外,请提供一些指向上述问题的指针。

从示例代码中大致了解一下

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class Test {
    private static final int MAX_LIMIT = 2;

    public static void main(String[] args) throws Exception {
        ArrayList<Package> packages = new ArrayList<>();

//change the path name
        String path = "G:/data.csv";

        parseCSVFile(path, packages);


        updateProductVersion(packages);

    }

    private static void updateProductVersion(ArrayList<Package> packages) {
        HashMap<String, String> latestVersionOfProducts = new HashMap<>(packages.size());
        for (Package p : packages) {
            String currentProduct = p.product;
            String currentVCode = Package.computeVCode(p.version);

            if (!latestVersionOfProducts.containsKey(currentProduct)) {
                latestVersionOfProducts.put(currentProduct, p.version);
            } else {
                String setVersion = latestVersionOfProducts.get(currentProduct);
                if (currentVCode.compareTo(Package.computeVCode(setVersion)) > 0) {
                    latestVersionOfProducts.put(currentProduct, p.version);
                }
            }
        }
        showLatestVersionsOfProducts(latestVersionOfProducts);

        detectOutdatedSystems(packages, latestVersionOfProducts);
    }

    private static void detectOutdatedSystems(ArrayList<Package> packages, HashMap<String, String> latestVersionOfProducts) {
        Set<Map.Entry<String, String>> products = latestVersionOfProducts.entrySet();
        boolean allNew = true;
        for (Map.Entry<String, String> product : products) {
            String productName = product.getKey();
            String productVersion = product.getValue();

            ArrayList<Package> outdates = new ArrayList<>();
            for (Package p : packages) {
                if (p.product.equalsIgnoreCase(productName) && !p.version.equalsIgnoreCase(productVersion)) {
                    outdates.add(p);
                }
            }
            if (outdates.size() >= MAX_LIMIT) {
                displayOutdates(outdates, productName);
                allNew = false;
            }
        }
        if (allNew) {
            System.out.println("All systems upto date");
        }
    }

    private static void displayOutdates(ArrayList<Package> outdates, String productName) {
        System.out.println(outdates.size() + " systems using outdated version of " + productName);
        for (Package aPackage : outdates) {
            System.out.println(aPackage);
        }
        System.out.println("---------------");
    }

    private static void showLatestVersionsOfProducts(HashMap<String, String> latestVersionOfProducts) {
        System.out.println("-----------------------------------------");
        System.out.println("latest versions detected are");
        Set<Map.Entry<String, String>> entries = latestVersionOfProducts.entrySet();
        System.out.println("\nVersion\t\tProduct");
        for (Map.Entry<String, String> entry : entries) {
            System.out.format("%-7s\t\t%s\n", entry.getValue(), entry.getKey());
        }
        System.out.println("-----------------------------------------");
    }


    private static void parseCSVFile(String path, ArrayList<Package> packages) throws FileNotFoundException {
        Scanner scanner = new Scanner(new File(path));
        while (scanner.hasNext())
            packages.add(new Package(scanner.nextLine()));
    }


    static class Package {
        String machine;//Server
        String type;//Database or OS or other
        String product;//Oracle or other
        String version;//version number


        public Package(String line) {
            String[] contents = line.split(",");
            machine = contents[0].trim();
            type = contents[1].trim();
            product = contents[2].trim();
            version = contents[3].trim();
        }

        public static String computeVCode(String version) {
            return version.replace(".", "").replaceAll(" ", "").toLowerCase().trim();
        }

        @Override
        public String toString() {
            return product + ' ' + type + " version:" + version + " is installed on " + machine;
        }
    }
}
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.util.*;
公开课考试{
专用静态最终整数最大值限制=2;
公共静态void main(字符串[]args)引发异常{
ArrayList packages=新的ArrayList();
//更改路径名
String path=“G:/data.csv”;
parseCSVFile(路径、包);
更新产品版本(软件包);
}
私有静态void updateProductVersion(ArrayList包){
HashMap latestVersionOfProducts=新的HashMap(packages.size());
用于(包p:包){
字符串currentProduct=p.product;
字符串currentVCode=Package.computeVCode(p.version);
如果(!latestVersionOfProducts.containsKey(currentProduct)){
最新版本的fproducts.put(当前产品,p.version);
}否则{
字符串setVersion=latestVersionOfProducts.get(currentProduct);
如果(currentVCode.compareTo(Package.computeVCode(setVersion))>0){
最新版本的fproducts.put(当前产品,p.version);
}
}
}
显示最新版本的产品(最新版本的产品);
检测数据系统(软件包、最新版本的产品);
}
私有静态void detectOutdatedSystems(ArrayList包、HashMap latestVersionOfProducts){
Set products=latestVersionOfProducts.entrySet();
布尔allNew=true;
用于(地图输入产品:产品){
字符串productName=product.getKey();
字符串productVersion=product.getValue();
ArrayList outdates=新的ArrayList();
用于(包p:包){
if(p.product.equalsIgnoreCase(productName)和&!p.version.equalsIgnoreCase(productVersion)){
过期。添加(p);
}
}
如果(过期.大小()>=最大限制){
显示过期日期(过期日期,产品名称);
全新=错误;
}
}
如果(全新){
System.out.println(“所有系统更新”);
}
}
私有静态void displayOutdates(ArrayList outdates,String productName){
System.out.println(outdates.size()+“系统使用过时版本的“+productName”);
对于(包装:过期){
System.out.println(打包);
}
System.out.println(“--------------”;
}
私有静态void显示产品的最新版本(HashMap latestVersionOfProducts){
System.out.println(“--------------------------------------------------------”;
System.out.println(“检测到最新版本”);
Set entries=latestVersionOfProducts.entrySet();
System.out.println(“\n转换\t\t产品”);
对于(Map.Entry:entries){
System.out.format(“%-7s\t\t%s\n”、entry.getValue()、entry.getKey());
}
System.out.println(“--------------------------------------------------------”;
}
私有静态void parseCSVFile(字符串路径,ArrayList包)引发FileNotFoundException{
扫描仪=新扫描仪(新文件(路径));
while(scanner.hasNext())
packages.add(新包(scanner.nextLine());
}
静态类包{
字符串计算机;//服务器
字符串类型;//数据库或操作系统或其他
字符串产品;//Oracle或其他
字符串版本;//版本号
公共包(字符串行){
String[]contents=line.split(“,”);
machine=contents[0]。trim();
类型=内容[1]。修剪();
product=目录[2]。trim();
版本=目录[3]。修剪();
}
公共静态字符串计算代码(字符串版本){
返回版本。replace(“.”,“”)。replaceAll(“,“”)。toLowerCase().trim();
}
@凌驾
公共字符串toString(){
退货产品+“”+类型+”版本:“+版本+”安装在“+机器上;
}
}
}

使用哪种数据结构最好

答案可能是主观的。我建议使用
列表
列表
这里是文件中的行列表,其中的
字符串数组
是用逗号分隔的单词数组

Path filePath = new File("resources/file.csv").toPath();
List<String[]> info = new ArrayList<String[]>();

try{
        Files.lines(filePath).forEach(line -> info.add(line.split(",")));

        List<String[]> oldSoftware = info.stream().filter(line -> Integer.parseInt(line[3].trim().replaceAll("\\.", "")) < 
                        info.stream().filter(line2 -> line2[2].equalsIgnoreCase(line[2])).map(line3 -> Integer.parseInt(line3[3].trim().replaceAll("\\.", ""))).max(Integer::compare).get()
                        ).collect(Collectors.toList());
}
catch (IOException e) {
        System.out.println("Can't read the file");
}
Path filePath=新文件(“resources/File.csv”).toPath();
列表信息=新的ArrayList();
试一试{
Files.line(filePath.forEach(line->info.add(line.split(“,”)));
列出oldSoftware=info.stream().filter(行->整数.parseInt(行[3].trim().replaceAll(“\\.”,”)<
info.stream()
).collect(Collectors.toList());
}
捕获(IOE异常){
System.out.println(“无法读取文件”);
}

从主方法中添加了以下方法。我不认为这是完全有效的,但它能够读取csv文件并通过许多测试用例

    private void findDuplicates(List<Inventory> inventoryList){

        Collections.sort(inventoryList, new SoftwareComparator());

        int size = inventoryList.size();
        int softwareCount=0;

        for(int i=0; i <size-1 ; i++){
            Inventory inv1 = inventoryList.get(i);
            Inventory inv2 = inventoryList.get(i+1);

            if(inv1.getSoftwareName().equals(inv2.getSoftwareName())){
                softwareCount++;
                if(inv1.getVersionNum().equals(inv2.getVersionNum()) || softwareCount==2 ){
                    if(!inv1.getServerName().equals(inv2.getServerName()) && softwareCount==2){
                        System.out.println(inv1.getSoftwareName() +"   "+ inv1.getVersionNum());
                    }
                }
            }else{
                softwareCount=0;
            }
        }

    }

class SoftwareComparator implements Comparator<Inventory>{

@Override
public int compare(Inventory obj1, Inventory obj2) {
    return obj1.getSoftwareName().compareTo(obj2.getSoftwareName());
}
private void find副本(清单清单清单){
集合。排序(inventor)