【问题标题】:Convert python dictionary into Java hashmap where value types are a mixture of data structures and lambda functions将python字典转换为Java hashmap,其中值类型是数据结构和lambda函数的混合
【发布时间】:2019-04-29 06:37:17
【问题描述】:

我正在尝试将我们讲师提供的 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"));
    }
}

【问题讨论】:

  • 请注意,您没有正确翻译您的 python 代码。 python 代码 mutates 第一个参数,它不 assign 给它。您正在尝试对您的参数进行分配。至于您的错误,您只需将 lambda 转换为适当的类型 - 您在编写 main 函数时将使用的类型。
  • @realSkeptic 这个骗子真的回答了这个问题吗?
  • @Jonas 它回答了主要部分,这就是 OP 收到他们提到的错误的原因。当然,正如我已经提到的,翻译还有其他问题,但是一旦对 lambdas 使用了正确的转换,他们就可以调试它的其余部分。
  • @realSkeptic "正确的转换" ...您真的建议在调用时将 Runnable 转换为 Object ,然后将 Object 转换回 Runnable 吗?我也看不到重复的地址。
  • @JonasWilms 鉴于练习的限制,这似乎是唯一的选择。这不是我在任何现实生活项目中都会做的事情,但家庭作业问题不是现实生活项目。

标签: java python lambda hashmap


【解决方案1】:

要表示具有“静态”属性的对象,您可以使用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”模式。

【讨论】:

  • 这如何回答这个问题?
  • @realSkeptic "我想知道我应该使用什么类型来覆盖我要存储为地图值的所有类型。"
  • OP 明确表示他们被指示保留名称-值数据结构(因此询问 value 应该是什么类型)。反正你呈现的肯定不是Singleton。
  • @realSkeptic 因为我没有将构造函数设为私有?如果他们被这样指示,说明是错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-10
  • 2014-09-25
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多