首页 > 解决方案 > 将python字典转换为Java hashmap,其中值类型是数据结构和lambda函数的混合

问题描述

我正在尝试将我们讲师提供的 python 代码转换为等效的 Java 代码。这部分代码应该从 txt 文件中读取,用正则表达式解析数据,并将它们存储为单词数组。本练习的一个限制是“data_storage_obj”用于模仿 JavaScript 对象,我们必须将它们保持为该键值格式。

该指令指示Java中最接近JavaScript Object的数据结构是“HashMap”。但是,因为每个键都映射到不同的数据结构来存储相应的信息,所以到目前为止我能想到的最好的类型是“对象”。但是,其中一个键映射到 lambda 函数,所以我收到这条错误消息,上面写着“错误:不兼容的类型:对象不是功能接口”。我想知道我应该使用什么类型来涵盖我要存储为地图值的所有类型。

导师提供的一段代码:

def extract_words(obj, path_to_file):
    with open(path_to_file) as f:
        obj['data'] = f.read()
    pattern = re.compile('[\W_]+')
    data_str = ''.join(pattern.sub(' ', obj['data']).lower())
    obj['data'] = data_str.split()

data_storage_obj = {
    'data' : [],
    'init' : lambda path_to_file : extract_words(data_storage_obj, path_to_file),
    'words' : lambda : data_storage_obj['data']
}

data_storage_obj['init'](sys.argv[1])

我一直在处理的 Java 代码:

public class Twelve{
    static void extract_words(Object obj, String path_to_file){
        System.out.println("extract_words()");
        if(obj instanceof HashMap){
            HashMap<String, Object> hashMap = (HashMap<String, Object>) obj;
            String file_data = "";
            try {
                file_data = (new String(Files.readAllBytes(Paths.get(path_to_file)))).replaceAll("[\\W_]+", " ").toLowerCase();
            } catch (IOException e) {
                e.printStackTrace();
            }
            hashMap.put("data", Arrays.asList(file_data.split(" ")));
            obj = hashMap;
        }
    }

    static HashMap<String, Object> data_storage_obj = new HashMap<>();

    public static void main(String[] args){
        ArrayList<String> data = new ArrayList<String>();
        data_storage_obj.put("data", data);
        data_storage_obj.put("init", path_to_file -> extract_words(data_storage_obj, path_to_file));
        data_storage_obj.put("words", data_storage_obj.get("data"));
    }
}

标签: javapythonlambdahashmap

解决方案


要表示具有“静态”属性的对象,您可以使用Singleton

  class DataStorage {
    ArrayList<String> data = new ArrayList<String>();

    void init(String pathToFile) { // ¹
     // ²
     try {
      this.data = (new String(Files.readAllBytes(Paths.get(pathToFile)))).replaceAll("[\\W_]+", " ").toLowerCase();
     } catch (IOException e) {
      e.printStackTrace();
     }            
    }

    ArrayList<String> getWords() { // ³
     return this.data;
    }
 }

从脚本语言(Python、JavaScript)转译成静态类型语言(Java)时,不能只保留动态结构。相反,您必须添加足够的类型,并且由于 Java 只有类,因此您需要在此处添加另一个类。

转译时,您应该从您转译成的语言中调整常见做法:

¹:对方法/变量使用 camelCase。

²:由于Java中没有独立的函数,extract_words可以直接与init方法合并(或者作为static方法添加到DataStorage)。

³:由于 Java 中没有真正的 getter/setter,因此您必须退回到“作为 getter 的方法”模式。


推荐阅读