Java “保存标准”;参考变量“;在爪哇

Java “保存标准”;参考变量“;在爪哇,java,Java,我正在为AP化学课制作一个分子查看器。我给每个元素分配了不同的颜色。例如,氢是白色的,碳是黑色的,氧是红色的 当我调用要渲染的新元素时,它如下所示: newAtom(x, y, z, color); 然后渲染原子 因为有上百种元素,有很多不同的颜色 我应该为所有这些颜色单独分类吗?例如: public class AtomColors { // By atomic number public final static Color H = new Color(1, 1, 1,

我正在为AP化学课制作一个分子查看器。我给每个元素分配了不同的颜色。例如,氢是白色的,碳是黑色的,氧是红色的

当我调用要渲染的新元素时,它如下所示:

newAtom(x, y, z, color);
然后渲染原子

因为有上百种元素,有很多不同的颜色

我应该为所有这些颜色单独分类吗?例如:

public class AtomColors {

    // By atomic number
    public final static Color H = new Color(1, 1, 1, 1);
    public final static Color He = new Color(1, 0.5f, 1, 1);
    public final static Color Li = new Color(0.5f, 1, 1, 1);
    public final static Color Be = new Color(1, 1, 1, 0.5f);
}
我不确定是否有一个标准的方法或这样做,哪种方法是最有效的。这是我的问题。这有更好的方法吗?

我认为这里最合适。枚举用于表示语言提供的结构中的相关常量

您可以表示如下颜色:

public enum ColorEnum {
    H(1, 1, 1, 1),
    He(1, 0.5f, 1, 1),
    Li(0.5f, 1, 1, 1),
    Be(1, 1, 1, 0.5f);

    private final float cyan;
    private final float magenta;
    private final float yellow;
    private final float black;

    EnumTest(float cyan, float megenta, float yellow, float black) {
        this.cyan = cyan;
        this.megenta = megenta;
        this.yellow = yellow;
        this.black = black;
    }

    public float getCyan() { return cyan; }
    public float getMegenta() { return megenta; }
    public float getYellow() { return yellow; }
    public float getBlack() { return black; }

    public Color getColor() {
            new Color(cyan, megenta, yellow, black);
    }
}
像这样使用它

newAtom(x, y, z, ColorEnum.He);
我建议,要获得关于这个主题的更多信息,请参考

  • 枚举类型-

我假设每种颜色都有一个相关的数字,您需要将其传递给分子查看器


您可以创建一个以元素名(或颜色名)为键的HashMap,该值将是颜色编号。

在您的设计中,颜色似乎是原子的属性。从面向对象设计的角度来看,我希望每个
Atom
类都有一个
Color
属性来存储其颜色。然后,
newAtom
方法将获取一个位置和一个要绘制的
Atom
对象,它将访问
Atom
的颜色属性,以确定要使用哪种颜色绘制它

如果你想保证原子的颜色是唯一的,我会使用质子的数量来生成颜色,例如,保持绿色和蓝色的值不变,并根据质子的数量生成不同的红色值(0到255)

我不确定是否有一个标准的方法或这样做,哪种方法是最有效的

没有“标准”的方法,但是你现在的方法应该很好

这样做没有效率问题。(事实上,无论您如何操作,效率都不太可能成为问题。性能瓶颈可能存在于3D几何体和渲染代码中。)

唯一的障碍是这种方法(或多或少)迫使您对数据结构进行非规范化;i、 e.在原子实例而不是元素上存储颜色@米凯拉克的回答清楚地说明了这一点。(@JayPatel的答案似乎也是这样……尽管他的造型有一些问题。从什么时候开始,“氦”是一种颜色??)

这有更好的方法吗

一种替代方法是使用每个命名元素的颜色填充
映射。这可能更灵活,尤其是如果您希望能够添加新元素和/或动态更改元素颜色(即不更改代码)

可能还有其他的



我的建议是不要“过度思考”。只要以一种你觉得很自然的方式来实现它,如果你的代码因为一些“非最佳”的数据结构设计决策而变得笨拙/重复/混乱。。。重新审视决策。

您拥有的代码很好。使用枚举是可以的。然而,如果你想让你的用户重新配置颜色,这将是困难的,因为你的变量是最终的。此外,如果您想让用户重新配置颜色,则不应将颜色存储在枚举中,因为作为最佳实践,枚举应该是不可变的。如果您想让用户以某种方式覆盖默认的着色方案,那么代码可能是这样的

public enum Element
{
    Ac("Actinium", 89),
    Ag("Silver", 47),
    Al("Aluminum", 13); 
    // etcetera

    private final String americanEnglishName;
    private final int atomicNumber;

    private Element(String americanEnglishName, int atomicNumber)
    {
        this.americanEnglishName = americanEnglishName;
        this.atomicNumber = atomicNumber;
    }

    public String getAmericanEnglishName()
    {
        return americanEnglishName;
    }

    public int getAtomicNumber()
    {
        return atomicNumber;
    }
}

class ApplicationSettings
{
    private static final Map<Element, Color> DEFAULT_COLORING;
    static
    {
        EnumMap<Element, Color> colorMap = 
            new EnumMap<Element, Color>(Element.class);
        colorMap.put(Element.Ac, new Color(1, 2, 3));
        colorMap.put(Element.Ag, Color.green);
        colorMap.put(Element.Al, Color.blue);
        // etcetera

        DEFAULT_COLORING = Collections.unmodifiableMap(colorMap);
    }

    private Map<Element, Color> _userPreferredColors = DEFAULT_COLORING;

    public Map<Element, Color> getUserPreferredColors()
    {
        return _userPreferredColors;
    }

    public void setUserPreferredColors(Map<Element, Color> userPreferredColors)
    {
        _userPreferredColors = userPreferredColors;
    }
}

class Application
{
    private ApplicationSettings _settings;

    public Application(ApplicationSettings settings)
    {
        _settings = settings;
    }

    private void run()
    {
        for(Element element : Element.values())
        {
            Color color = _settings.getUserPreferredColors().get(element);
            System.out.println(element.getAmericanEnglishName() + "=" + color);
        }

    }

    public static void main(String[] args) 
    {
        ApplicationSettings settings = new ApplicationSettings();
        Application app = new Application(settings);
        app.run();
    }    
}
公共枚举元素
{
Ac(“锕”,89),
银(“银”,47),
铝(“铝”,13);
//等等
私有最终字符串americanEnglishName;
私有最终整数原子数;
私有元素(字符串americanEnglishName,int-atomicNumber)
{
this.americanEnglishName=americanEnglishName;
this.atomicNumber=原子数;
}
公共字符串getAmericanEnglishName()
{
返回美国英语名称;
}
public int getAtomicNumber()
{
返回原子数;
}
}
类应用程序设置
{
私有静态最终贴图默认_着色;
静止的
{
EnumMap colorMap=
新的枚举映射(Element.class);
colorMap.put(Element.Ac,新颜色(1,2,3));
colorMap.put(Element.Ag,Color.green);
colorMap.put(Element.Al,Color.blue);
//等等
默认颜色=集合。不可修改映射(颜色映射);
}
私有映射_userPreferredColors=默认颜色;
公共地图getUserPreferredColors()
{
返回_userPreferredColors;
}
public void setUserPreferredColors(映射userPreferredColors)
{
_userPreferredColors=userPreferredColors;
}
}
班级申请
{
专用应用程序设置\u设置;
公共应用程序(应用程序设置)
{
_设置=设置;
}
私家车
{
对于(元素:Element.values())
{
Color Color=\u settings.getUserPreferredColors().get(元素);
System.out.println(element.getAmericanEnglishName()+“=”+颜色);
}
}
公共静态void main(字符串[]args)
{
ApplicationSettings设置=新的ApplicationSettings();
应用程序应用程序=新应用程序(设置);
app.run();
}    
}

任何时候,当您拥有编译时已知的常量列表(如周期表中的元素)时,这都是使用枚举的正确时机。枚举由实例控制,并且是开箱即用的类型安全的。随着需求的增长,您可以灵活地添加枚举方法,甚至是常量特定方法

此外,已经有优化的集合类可以简化使用枚举常量集合的工作