在没有数据库的情况下查询 Java 对象

2022-09-04 04:14:45

注意:小问题很长。我要给一个赏金,以获得最好的答案。

我试图做的是在对象上查询。以下是详细信息。我有一个名为 .所以我解析了它并保留在列表中employee.txt

public static List<Employee> employeeList = new LinkedList<>();

然后这是我的查询逻辑。

从用户那里获取查询,然后对其进行分析。以下是通过列表进行查询的逻辑。

例如:这是查询

select * from Employee where id > 10

我的代码

String valueToCompare = split[5];  //10
EmployeeCriteria criteria = new EmployeeCriteria(
        isId, isName, isSalary, expression,
        valueToCompare);
result = EmployeeData.findAll(
        EmployeeData.employeeList, criteria);

这是 findAll 方法

public static List<Employee> findAll(List<Employee> coll,
            ISearch<Employee> chk) {
        List<Employee> l = new LinkedList<Employee>();
        for (Employee obj : coll) {
            if (chk.search(new Employee(obj)))
                l.add(obj);
        }
        return l;
    }

这是我的搜索方法

/**
     * Based on the type provided and for given expression it check against the
     * given value
     */

    @Override
    public boolean search(Employee obj) {
        if (expression.equals(EQUAL)) {
            if (isId()) {
                if (obj.getId() == Long.parseLong(valueToCompare)) {
                    return true;
                }
            } else if (isName()) {
                if (obj.getName().equals(valueToCompare)) {
                    return true;
                }
            } else if (isSalary()) {
                if (obj.getSalary() == Long.parseLong(valueToCompare)) {
                    return true;
                }
            } else {
                System.err.println(UserMessage.INVALIDCOLUMN_NAME);
            }

        } else if (expression.equals(NOT_EQUAL)) {
            if (isId()) {
                if (!(obj.getId() == Long.parseLong(valueToCompare))) {
                    return true;
                }
            } else if (isName()) {
                if (!(obj.getName().equals(valueToCompare))) {
                    return true;
                }
            } else if (isSalary()) {
                if (!(obj.getSalary() == Long.parseLong(valueToCompare))) {
                    return true;
                }
            } else {
                System.err.println(UserMessage.INVALIDCOLUMN_NAME);
            }

        } else if (expression.equals(GREATER)) {
            if (isId()) {
                if ((obj.getId() > Long.parseLong(valueToCompare))) {
                    return true;
                }
            } else if (isSalary()) {
                if ((obj.getSalary() > Long.parseLong(valueToCompare))) {
                    return true;
                }
            } else {
                System.err.println(UserMessage.INVALIDCOLUMN_NAME);
            }

        } else if (expression.equals(LESSER)) {
            if (isId()) {
                if ((obj.getId() < Long.parseLong(valueToCompare))) {
                    return true;
                }
            } else if (isSalary()) {
                if ((obj.getSalary() < Long.parseLong(valueToCompare))) {
                    return true;
                }
            } else {
                System.err.println(UserMessage.INVALID_IDENTIFIER);
            }

        }

        return false;
    }

如果您想查看任何其他代码,请告诉我。

我只想知道,

首先,使用正确的数据结构吗?这是表现良好吗?任何增强功能以表现良好?LinkedList

有什么更好的方法可以实现这一目标吗?

以下是几个示例查询:

select * where ID > 100
select * where Name != Ramesh
select * where Salary < 500000
select Name order by Name
select ID

感谢您的任何帮助。赏金将在2天后提供。我现在做不到。

注意2:这是一个测试,用于检查我的数据管理技能,我不能使用任何数据库。


答案 1

不,这根本不好。您每次都在搜索员工。因此,如果您有100万名员工,您将在返回正确的员工之前搜索所有100万名员工。更糟糕的是,如果它不存在,你将不得不彻底搜索,然后才能知道它是否存在。N

这是否适用于生产环境?如果是这样,那么只需使用SQLite或其他一些简单的数据库。您希望使用索引写入一次并读取多次。我再怎么强调也不过分,你正在写的东西会有错误,相反,你应该使用已经测试过的东西。

假设这不是为了生产,你只是在玩得开心,那么你想模仿数据库在现实生活中的作用。它们创建索引。索引通常最好描述为 。Map<String, List<Employee>>

这个想法是,最初从磁盘读取数据是昂贵的。但你读过一次。对于每个维度、、、、等...您想要创建单独的索引。NameSalaryID

因此,假设您正在按 ID 创建所有员工的索引。您可能希望执行如下操作:

Map<String, Employee> employeesById = new HashMap<>();

for(Employee e : employees) { 
  employeesById.put(e.getId(), e);
}

上述假设员工 ID 是唯一的。如果不是,则需要创建一个 .例如,对于按名称划分的索引:List<Employee>

Map<String,List<Employee>> employeesByName = new HashMap<>();

for(Employee e : employees) { 
  employeesByName.get(e.getName()).add(e); // Make sure to create the array if it doesn't exist
}

所以现在,为了阅读,假设你可以简单地返回 。SELECT * FROM employees where id = 123;employeesById.get("123")

此解决方案是 。随着文件变大,您不会有任何性能损失。这可能是最快的解决方案。O(1)


答案 2

要添加到Amir的答案中,您还可以使用代替.数据库通常不会将索引创建为哈希映射,而是创建平衡的二叉树,这就是Java的类。TreeMap<>HashMap<>TreeMap<>

http://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html

HashMap<>在键上有 O(1) 查找, 但只在键上完全匹配。 在键上具有 O(log n) 查找功能,但允许范围查找 、) 和在键范围 () 上映射分区。TreeMap<>higherKeylowerKeysubMap

重复的问题可以通过不允许它们(唯一键)或将值存储在列表中并在子集(非唯一键)上进行线性搜索来解决。