Java 独一无二的对象

Java 独一无二的对象,java,Java,我想为某些属性创建一个独一无二的对象: import java.util.HashMap; public class SourceLanguage { private final String name; private static HashMap<String,SourceLanguage> existing; private SourceLanguage(String name){ this.name = name; }

我想为某些属性创建一个独一无二的对象:

import java.util.HashMap;

public class SourceLanguage {
    private  final String name;
    private static HashMap<String,SourceLanguage> existing;

    private SourceLanguage(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public static SourceLanguage get(String name){
        if(existing==null){
            existing = new HashMap<>();
            SourceLanguage sl = new SourceLanguage(name);
            existing.put(name.toLowerCase(),sl);
            return sl;
        }
        SourceLanguage check = existing.get(name);
        if(check==null){
            SourceLanguage sl = new SourceLanguage(name);
            existing.put(name.toLowerCase(),sl);
            return sl;
        }else {
            return check;
        }
    }
}
import java.util.HashMap;
公共类源语言{
私有最终字符串名;
私有静态HashMap存在;
专用源语言(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
公共静态SourceLanguage get(字符串名称){
if(现有==null){
existing=新HashMap();
SourceLanguage sl=新的SourceLanguage(名称);
existing.put(name.toLowerCase(),sl);
返回sl;
}
SourceLanguage check=existing.get(名称);
如果(检查==null){
SourceLanguage sl=新的SourceLanguage(名称);
existing.put(name.toLowerCase(),sl);
返回sl;
}否则{
退货检查;
}
}
}
我想使用这个类的对象作为另一个映射中的键

我觉得这有点过分了。
是否有更简单的方法来实现目标?

您可以考虑使用。通过这种方式,
SourceLanguage
对象的行为可以与强制其唯一性的行为分离。它们也可能变得更加复杂,彼此独立;注册表可以处理注释中描述的内存泄漏,而不会扰乱
SourceLanguage


SourceLanguage
和注册表类放在同一个包中,但要使
SourceLanguage
类包可见(或者给它一个
protected
构造函数)然后外部组件将无法直接实例化
SourceLanguage
,必须通过注册表。

您可以考虑使用。通过这种方式,
SourceLanguage
对象的行为可以与强制其唯一性的行为分离。它们也可能变得更加复杂,彼此独立;注册表可以处理注释中描述的内存泄漏,而不会扰乱
SourceLanguage


SourceLanguage
和注册表类放在同一个包中,但要使
SourceLanguage
类包可见(或者给它一个
protected
构造函数)然后外部组件将无法直接实例化
SourceLanguage
,必须通过注册表。

除非我遗漏了什么,否则我认为您可以这样做

public class SourceLanguage {
    private  final String name;
    private static HashMap<String,SourceLanguage> existing = new HashMap<String, SourceLanguage>();

    private SourceLanguage(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public static SourceLanguage get(String name){
        SourceLanguage ret = existing.get(name.toLowerCase());
        if(ret == null) {
            ret = new SourceLanguage(name);
            existing.put(name.toLowerCase(),ret);
        }
        return ret;
    }
}
公共类源语言{
私有最终字符串名;
private static HashMap existing=new HashMap();
专用源语言(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
公共静态SourceLanguage get(字符串名称){
SourceLanguage ret=existing.get(name.toLowerCase());
if(ret==null){
ret=新的源语言(名称);
existing.put(name.toLowerCase(),ret);
}
返回ret;
}
}

除非我遗漏了什么,否则我认为你可以这样做

public class SourceLanguage {
    private  final String name;
    private static HashMap<String,SourceLanguage> existing = new HashMap<String, SourceLanguage>();

    private SourceLanguage(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public static SourceLanguage get(String name){
        SourceLanguage ret = existing.get(name.toLowerCase());
        if(ret == null) {
            ret = new SourceLanguage(name);
            existing.put(name.toLowerCase(),ret);
        }
        return ret;
    }
}
公共类源语言{
私有最终字符串名;
private static HashMap existing=new HashMap();
专用源语言(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
公共静态SourceLanguage get(字符串名称){
SourceLanguage ret=existing.get(name.toLowerCase());
if(ret==null){
ret=新的源语言(名称);
existing.put(name.toLowerCase(),ret);
}
返回ret;
}
}

我强烈建议您避免对缓存使用强引用。如果这是线程安全的,您还需要一些同步

public class SourceLanguage {
    private final String name;
    private final static Map<String, SoftReference<SourceLanguage>> cache
        = new HashMap<String, SoftReference<SourceLanguage>>();

    private SourceLanguage(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public static SourceLanguage get(String name){
        final String key = name.toLowerCase();
        SourceLanguage lang = null;
        synchronized (cache) {
            SoftReference<SourceLanguage> ref = cache.get(key);
            if (ref != null) {
                lang = ref.get();
            }
            if (lang == null) {
                SourceLanguage sl = new SourceLanguage(name);
                cache.put(key, new SoftReference<SourceLanguage>(sl);
            }
        }
        return lang;
    }
}
公共类源语言{
私有最终字符串名;
私有最终静态映射缓存
=新HashMap();
专用源语言(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
公共静态SourceLanguage get(字符串名称){
最后一个字符串键=name.toLowerCase();
SourceLanguage=null;
已同步(缓存){
SoftReference ref=cache.get(键);
如果(ref!=null){
lang=ref.get();
}
if(lang==null){
SourceLanguage sl=新的SourceLanguage(名称);
cache.put(键,新的软引用(sl);
}
}
还郎;
}
}

我强烈建议您避免对缓存进行强引用。如果这是线程安全的,您还需要一些同步

public class SourceLanguage {
    private final String name;
    private final static Map<String, SoftReference<SourceLanguage>> cache
        = new HashMap<String, SoftReference<SourceLanguage>>();

    private SourceLanguage(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public static SourceLanguage get(String name){
        final String key = name.toLowerCase();
        SourceLanguage lang = null;
        synchronized (cache) {
            SoftReference<SourceLanguage> ref = cache.get(key);
            if (ref != null) {
                lang = ref.get();
            }
            if (lang == null) {
                SourceLanguage sl = new SourceLanguage(name);
                cache.put(key, new SoftReference<SourceLanguage>(sl);
            }
        }
        return lang;
    }
}
公共类源语言{
私有最终字符串名;
私有最终静态映射缓存
=新HashMap();
专用源语言(字符串名称){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
公共静态SourceLanguage get(字符串名称){
最后一个字符串键=name.toLowerCase();
SourceLanguage=null;
已同步(缓存){
SoftReference ref=cache.get(键);
如果(ref!=null){
lang=ref.get();
}
if(lang==null){
SourceLanguage sl=新的SourceLanguage(名称);
cache.put(键,新的软引用(sl);
}
}
还郎;
}
}

您所尝试的内容属于“实习”的一般概念。一般来说,它很容易出现内存泄漏,但我怀疑这是否会成为您的问题,因为不会有那么多语言

我的建议是使用
ConcurrentHashMap

private static final ConcurrentMap<String, SourceLanguage> existing = 
  new ConcurrentHashMap<>();

public static SourceLanguage get(String name) {
  name = name.toLowerCase();
  final SourceLanguage old = existing.get(name);
  if (old != null) return old;
  final SourceLanguage 
    created = new SourceLanguage(name),
    justPut = existing.putIfAbsent(name, created);
  return justPut != null? justPut : created;
}
private static final ConcurrentMap existing=
新的ConcurrentHashMap();
公共静态SourceLanguage get(字符串名称){
name=name.toLowerCase();
final SourceLanguage old=existing.get(名称);
如果(old!=null)返回old;
最终源语言
已创建=新资源