import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.prefs.Preferences; /**
* Windows下读取注册表的工具类
*
* 使用这些方法的示例如下:
*
* 下面的方法从给定路径检索键的值:
*
* String hex = WinRegistry.valueForKey(WinRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update", "AUOptions");
*
* 此方法检索指定路径的所有数据(以键和值的形式):
*
* Map<String, String> map = WinRegistry.valuesForPath(WinRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WSMAN");
*
* 此方法从给定路径递归检索键的值:
*
* String val = WinRegistry.valueForKeyPath(WinRegistry.HKEY_LOCAL_MACHINE, "System", "TypeID");
*
* 并且这个方法递归地从给定路径中检索一个键的所有值:
*
* List<String> list = WinRegistry.valuesForKeyPath( WinRegistry.HKEY_LOCAL_MACHINE, //HKEY "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", //path "DisplayName" //Key );
*
* 在上面的代码中,我检索了Windows系统中所有已安装的软件名称。
*
* 注意:请参阅这些方法的文档。
*
* 这个检索给定路径的所有子键:
*
* List<String> list3 = WinRegistry.subKeysForPath(WinRegistry.HKEY_CURRENT_USER, "Software");
*
* 注意:在这个过程中,我只修改了阅读目的的方法,而不是像createKey、删除Key等写作目的的方法。它们仍然和我收到的一样。
*
* https://cloud.tencent.com/developer/ask/43600
*/
@SuppressWarnings("all")
public class WinRegistry { private static final int REG_SUCCESS = 0;
private static final int REG_NOTFOUND = 2;
private static final int KEY_READ = 0x20019;
private static final int REG_ACCESSDENIED = 5;
private static final int KEY_ALL_ACCESS = 0xf003f;
public static final int HKEY_CLASSES_ROOT = 0x80000000;
public static final int HKEY_CURRENT_USER = 0x80000001;
public static final int HKEY_LOCAL_MACHINE = 0x80000002;
private static final String CLASSES_ROOT = "HKEY_CLASSES_ROOT";
private static final String CURRENT_USER = "HKEY_CURRENT_USER";
private static final String LOCAL_MACHINE = "HKEY_LOCAL_MACHINE";
private static Preferences userRoot = Preferences.userRoot();
private static Preferences systemRoot = Preferences.systemRoot();
private static Class<? extends Preferences> userClass = userRoot.getClass();
private static Method regOpenKey = null;
private static Method regCloseKey = null;
private static Method regQueryValueEx = null;
private static Method regEnumValue = null;
private static Method regQueryInfoKey = null;
private static Method regEnumKeyEx = null;
private static Method regCreateKeyEx = null;
private static Method regSetValueEx = null;
private static Method regDeleteKey = null;
private static Method regDeleteValue = null; static {
try {
regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey", new Class[] {int.class, byte[].class, int.class});
regOpenKey.setAccessible(true);
regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey", new Class[] {int.class});
regCloseKey.setAccessible(true);
regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx", new Class[] {int.class, byte[].class});
regQueryValueEx.setAccessible(true);
regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue", new Class[] {int.class, int.class, int.class});
regEnumValue.setAccessible(true);
regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1", new Class[] {int.class});
regQueryInfoKey.setAccessible(true);
regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx", new Class[] {int.class, int.class, int.class});
regEnumKeyEx.setAccessible(true);
regCreateKeyEx = userClass.getDeclaredMethod("WindowsRegCreateKeyEx", new Class[] {int.class, byte[].class});
regCreateKeyEx.setAccessible(true);
regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx", new Class[] {int.class, byte[].class, byte[].class});
regSetValueEx.setAccessible(true);
regDeleteValue = userClass.getDeclaredMethod("WindowsRegDeleteValue", new Class[] {int.class, byte[].class});
regDeleteValue.setAccessible(true);
regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey", new Class[] {int.class, byte[].class});
regDeleteKey.setAccessible(true);
}
catch (Exception e) {
e.printStackTrace();
}
} /**
* Reads value for the key from given path
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param path
* @param key
* @return the value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public static String valueForKey(int hkey, String path, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
if (hkey == HKEY_LOCAL_MACHINE)
return valueForKey(systemRoot, hkey, path, key);
else if (hkey == HKEY_CURRENT_USER)
return valueForKey(userRoot, hkey, path, key);
else
return valueForKey(null, hkey, path, key);
} /**
* Reads all key(s) and value(s) from given path
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param path
* @return the map of key(s) and corresponding value(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public static Map<String, String> valuesForPath(int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
if (hkey == HKEY_LOCAL_MACHINE)
return valuesForPath(systemRoot, hkey, path);
else if (hkey == HKEY_CURRENT_USER)
return valuesForPath(userRoot, hkey, path);
else
return valuesForPath(null, hkey, path);
} /**
* Read all the subkey(s) from a given path
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param path
* @return the subkey(s) list
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static List<String> subKeysForPath(int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (hkey == HKEY_LOCAL_MACHINE)
return subKeysForPath(systemRoot, hkey, path);
else if (hkey == HKEY_CURRENT_USER)
return subKeysForPath(userRoot, hkey, path);
else
return subKeysForPath(null, hkey, path);
} /**
* Create a key
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void createKey(int hkey, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int [] ret;
if (hkey == HKEY_LOCAL_MACHINE) {
ret = createKey(systemRoot, hkey, key);
regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
} else if (hkey == HKEY_CURRENT_USER) {
ret = createKey(userRoot, hkey, key);
regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
} else
throw new IllegalArgumentException("hkey=" + hkey);
if (ret[1] != REG_SUCCESS)
throw new IllegalArgumentException("rc=" + ret[1] + " key=" + key);
} /**
* Write a value in a given key/value name
* @param hkey
* @param key
* @param valueName
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void writeStringValue(int hkey, String key, String valueName, String value)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (hkey == HKEY_LOCAL_MACHINE)
writeStringValue(systemRoot, hkey, key, valueName, value);
else if (hkey == HKEY_CURRENT_USER)
writeStringValue(userRoot, hkey, key, valueName, value);
else
throw new IllegalArgumentException("hkey=" + hkey);
} /**
* Delete a given key
* @param hkey
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteKey(int hkey, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE)
rc = deleteKey(systemRoot, hkey, key);
else if (hkey == HKEY_CURRENT_USER)
rc = deleteKey(userRoot, hkey, key);
if (rc != REG_SUCCESS)
throw new IllegalArgumentException("rc=" + rc + " key=" + key);
} /**
* delete a value from a given key/value name
* @param hkey
* @param key
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static void deleteValue(int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int rc = -1;
if (hkey == HKEY_LOCAL_MACHINE)
rc = deleteValue(systemRoot, hkey, key, value);
else if (hkey == HKEY_CURRENT_USER)
rc = deleteValue(userRoot, hkey, key, value);
if (rc != REG_SUCCESS)
throw new IllegalArgumentException("rc=" + rc + " key=" + key + " value=" + value);
} // ===================== private static int deleteValue(Preferences root, int hkey, String key, String value)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS)});
if (handles[1] != REG_SUCCESS)
return handles[1]; // can be REG_NOTFOUND, REG_ACCESSDENIED
int rc =((Integer) regDeleteValue.invoke(root, new Object[] {new Integer(handles[0]), toCstr(value)})).intValue();
regCloseKey.invoke(root, new Object[] { new Integer(handles[0])});
return rc;
} private static int deleteKey(Preferences root, int hkey, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int rc =((Integer) regDeleteKey.invoke(root, new Object[] {new Integer(hkey), toCstr(key)})).intValue();
return rc; // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
} private static String valueForKey(Preferences root, int hkey, String path, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(path), new Integer(KEY_READ)});
if (handles[1] != REG_SUCCESS)
throw new IllegalArgumentException("The system can not find the specified path: '"+getParentKey(hkey)+"\\"+path+"'");
byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {new Integer(handles[0]), toCstr(key)});
regCloseKey.invoke(root, new Object[] {new Integer(handles[0])});
return (valb != null ? parseValue(valb) : queryValueForKey(hkey, path, key));
} private static String queryValueForKey(int hkey, String path, String key) throws IOException {
return queryValuesForPath(hkey, path).get(key);
} private static Map<String,String> valuesForPath(Preferences root, int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
HashMap<String, String> results = new HashMap<String,String>();
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(path), new Integer(KEY_READ)});
if (handles[1] != REG_SUCCESS)
throw new IllegalArgumentException("The system can not find the specified path: '"+getParentKey(hkey)+"\\"+path+"'");
int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[] {new Integer(handles[0])});
int count = info[2]; // Fixed: info[0] was being used here
int maxlen = info[4]; // while info[3] was being used here, causing wrong results
for(int index=0; index<count; index++) {
byte[] valb = (byte[]) regEnumValue.invoke(root, new Object[] {new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)});
String vald = parseValue(valb);
if(valb == null || vald.isEmpty())
return queryValuesForPath(hkey, path);
results.put(vald, valueForKey(root, hkey, path, vald));
}
regCloseKey.invoke(root, new Object[] {new Integer(handles[0])});
return results;
} /**
* Searches recursively into the path to find the value for key. This method gives
* only first occurrence value of the key. If required to get all values in the path
* recursively for this key, then {@link #valuesForKeyPath(int hkey, String path, String key)}
* should be used.
* @param hkey
* @param path
* @param key
* @param list
* @return the value of given key obtained recursively
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public static String valueForKeyPath(int hkey, String path, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
String val;
try {
val = valuesForKeyPath(hkey, path, key).get(0);
} catch(IndexOutOfBoundsException e) {
throw new IllegalArgumentException("The system can not find the key: '"+key+"' after "
+ "searching the specified path: '"+getParentKey(hkey)+"\\"+path+"'");
}
return val;
} /**
* Searches recursively into given path for particular key and stores obtained value in list
* @param hkey
* @param path
* @param key
* @param list
* @return list containing values for given key obtained recursively
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
public static List<String> valuesForKeyPath(int hkey, String path, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
List<String> list = new ArrayList<String>();
if (hkey == HKEY_LOCAL_MACHINE)
return valuesForKeyPath(systemRoot, hkey, path, key, list);
else if (hkey == HKEY_CURRENT_USER)
return valuesForKeyPath(userRoot, hkey, path, key, list);
else
return valuesForKeyPath(null, hkey, path, key, list);
} private static List<String> valuesForKeyPath(Preferences root, int hkey, String path, String key, List<String> list)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
if(!isDirectory(root, hkey, path)) {
takeValueInListForKey(hkey, path, key, list);
} else {
List<String> subKeys = subKeysForPath(root, hkey, path);
for(String subkey: subKeys) {
String newPath = path+"\\"+subkey;
if(isDirectory(root, hkey, newPath))
valuesForKeyPath(root, hkey, newPath, key, list);
takeValueInListForKey(hkey, newPath, key, list);
}
}
return list;
} /**
* Takes value for key in list
* @param hkey
* @param path
* @param key
* @param list
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws IOException
*/
private static void takeValueInListForKey(int hkey, String path, String key, List<String> list)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
String value = valueForKey(hkey, path, key);
if(value != null)
list.add(value);
} /**
* Checks if the path has more subkeys or not
* @param root
* @param hkey
* @param path
* @return true if path has subkeys otherwise false
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static boolean isDirectory(Preferences root, int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return !subKeysForPath(root, hkey, path).isEmpty();
} private static List<String> subKeysForPath(Preferences root, int hkey, String path)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
List<String> results = new ArrayList<String>();
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(path), new Integer(KEY_READ)});
if (handles[1] != REG_SUCCESS)
throw new IllegalArgumentException("The system can not find the specified path: '"+getParentKey(hkey)+"\\"+path+"'");
int[] info = (int[]) regQueryInfoKey.invoke(root, new Object[] {new Integer(handles[0])});
int count = info[0]; // Fix: info[2] was being used here with wrong results. Suggested by davenpcj, confirmed by Petrucio
int maxlen = info[3]; // value length max
for(int index=0; index<count; index++) {
byte[] valb = (byte[]) regEnumKeyEx.invoke(root, new Object[] {new Integer(handles[0]), new Integer(index), new Integer(maxlen + 1)});
results.add(parseValue(valb));
}
regCloseKey.invoke(root, new Object[] {new Integer(handles[0])});
return results;
} private static int [] createKey(Preferences root, int hkey, String key)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return (int[]) regCreateKeyEx.invoke(root, new Object[] {new Integer(hkey), toCstr(key)});
} private static void writeStringValue(Preferences root, int hkey, String key, String valueName, String value)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS)});
regSetValueEx.invoke(root, new Object[] {new Integer(handles[0]), toCstr(valueName), toCstr(value)});
regCloseKey.invoke(root, new Object[] {new Integer(handles[0])});
} /**
* Makes cmd query for the given hkey and path then executes the query
* @param hkey
* @param path
* @return the map containing all results in form of key(s) and value(s) obtained by executing query
* @throws IOException
*/
private static Map<String, String> queryValuesForPath(int hkey, String path) throws IOException {
String line;
StringBuilder builder = new StringBuilder();
Map<String, String> map = new HashMap<String, String>();
Process process = Runtime.getRuntime().exec("reg query \""+getParentKey(hkey)+"\\" + path + "\"");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = reader.readLine()) != null) {
if(!line.contains("REG_"))
continue;
StringTokenizer tokenizer = new StringTokenizer(line, " \t");
while(tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if(token.startsWith("REG_"))
builder.append("\t ");
else
builder.append(token).append(" ");
}
String[] arr = builder.toString().split("\t");
map.put(arr[0].trim(), arr[1].trim());
builder.setLength(0);
}
return map;
} /**
* Determines the string equivalent of hkey
* @param hkey
* @return string equivalent of hkey
*/
private static String getParentKey(int hkey) {
if(hkey == HKEY_CLASSES_ROOT)
return CLASSES_ROOT;
else if(hkey == HKEY_CURRENT_USER)
return CURRENT_USER;
else if(hkey == HKEY_LOCAL_MACHINE)
return LOCAL_MACHINE;
return null;
} /**
*Intern method which adds the trailing \0 for the handle with java.dll
* @param str String
* @return byte[]
*/
private static byte[] toCstr(String str) {
if(str == null)
str = "";
return (str += "\0").getBytes();
} /**
* Method removes the trailing \0 which is returned from the java.dll (just if the last sign is a \0)
* @param buf the byte[] buffer which every read method returns
* @return String a parsed string without the trailing \0
*/
private static String parseValue(byte buf[]) {
if(buf == null)
return null;
String ret = new String(buf);
if(ret.charAt(ret.length()-1) == '\0')
return ret.substring(0, ret.length()-1);
return ret;
}
}

Java Windows下读取注册表的工具类的更多相关文章

  1. WinCE下读取注册表获得SD路径

    WinCE下读取注册表获得SD路径 [要点]WinCE注册表中[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\] 下键Folde ...

  2. 读取注册表获取Windows系统XP/7/8/10类型(使用wcscmp比较wchar[]内容)

    很多方案是采用GetVersion.GetVersionEx这两个API来查询操作系统的版本号来判断当前的操作系统是Windows系列中的哪个,在Win10没有出现前,这种方法是行的通的,但是Win1 ...

  3. inno setup读取注册表遇到的一个坑

    一.背景 目前,公司针对PR开发的一个插件需要发布到64位系统上.该插件包括一个prm格式的文件和若干个DLL文件.其中,prm文件需要复制到PR公共插件目录下,DLL需要复制到Windows系统目录 ...

  4. C#读取注册表信息

    注册表是视窗系统的一个核心的数据库,在这个数据库中存放中与系统相关的各种参数,这些参数直接控制中系统的启动.硬件的驱动程序安装信息以及在视窗系统上运行的各种应用程序的注册信息等.这就意味着,如果注册表 ...

  5. c++读取注册表的实例

    // CRegisterTest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #in ...

  6. 从零开始学 Java - Windows 下安装 Tomcat

    谁都想分一杯羹 没有一个人是真正的无私到伟大的,我们试着说着做自己,与人为善,世界和平!殊不知,他们的真实目的当你知道后,你会被恶心到直摇头并下意识地迅速跑开,下辈子都不想见到他.不过,他没错,你也没 ...

  7. Delphi在win7/vista下写注册表等需要管理员权限的解决方案

    看到论坛好多人问win7下写注册表的问题,我结合自己的理解写了一点东西,首先声明一下,本人初学Delphi,水平有限,大家见笑了,有什么不对之处请老鸟多指点. [背景]win7/Vista提供的UAC ...

  8. 注册表对比工具(Regshot) V2.0.1 中文绿色版

    软件名称: 注册表对比工具(Regshot)软件语言: 简体中文授权方式: 免费软件运行环境: Win7 / Vista / WinXP软件大小: 263KB图片预览: 软件简介:Regshot 是一 ...

  9. C++ 64位操作系统调用 RegOpenKey() 读取注册表,返回 2, ERROR_FILE_NOT_FOUND

    环境:64位操作系统, VS2017 首先在命令行执行 REG ADD HKLM\Software\seastarsun /v serial /t REG_SZ /d 58ae4cb077a4e1 在 ...

随机推荐

  1. 从HDFS的写入和读取中,我发现了点东西

    摘要:从HDFS的写入和读取中,我们能学习到什么? 本文分享自华为云社区<从HDFS的写入和读取中,我们能学习到什么>,作者: breakDawn . 最近开发过程涉及了一些和文件读取有关 ...

  2. 项目可以怎么规范Git commit ?

    通常情况下,commit message应该清晰明了,说明本次提交的目的,具体做了什么操作.但是在日常开发中,大家的commit message都比较随意,中英文混合使用的情况有时候很常见,这就导致后 ...

  3. Arthas之类操作

    Arthas之类操作 1. classLoader 查询当前JVM中存在的classloader classloader name numberOfInstances loadedCountTotal ...

  4. js file对象 文件大小转换可视容易阅读的单位

    function returnFileSize(number) { if(number < 1024) { return number + 'bytes'; } else if(number & ...

  5. Delete、truncate、drop都是删除语句,它们有什么分别?

    delete 属于DML语句,删除数据,保留表结构,需要commit,可以回滚,如果数据量大,很慢. truncate 属于DDL语句,删除所有数据,保留表结构,自动commit,不可以回滚,一次全部 ...

  6. 什么是 AOP?

    在软件开发过程中,跨越应用程序多个点的功能称为交叉问题.这些交叉问题与 应用程序的主要业务逻辑不同.因此,将这些横切关注与业务逻辑分开是面向方 面编程(AOP)的地方.

  7. MM32F0140 UART1硬件自动波特率校准功能的使用

    目录: 1.MM32F0140简介 2.UART自动波特率校准应用场景 3.MM32F0140 UART自动波特率校准原理简介 4.MM32F0140 UART1 NVIC硬件自动波特率配置以及初始化 ...

  8. servlet中的ServletContext对象

    ServletContext官方叫Servlet上下文.服务器会为每一个Web应用创建一个ServletContext对象.这个对象全局唯一,而且Web应用 中的所有Servlet都共享这个对象(在整 ...

  9. 决策树算法4:CHAID

    原理: 其中 n = a+b+c+d 卡方计算(例子)使用 sklearn完成 data.csv中的部分数据 #如何使用卡方检测相关度 from sklearn.feature_selection i ...

  10. Matlab解析LQR与MPC的关系

    mathworks社区中的这个资料还是值得一说的. 1 openExample('mpc/mpccustomqp') 我们从几个角度来解析两者关系,简单的说就是MPC是带了约束的LQR. 在陈虹模型预 ...