Java枚举按数字范围搜索
是否可以像下面这样进行枚举Java枚举按数字范围搜索,java,enums,Java,Enums,是否可以像下面这样进行枚举 enum { 10 poor 100 rich 1000 very_rich } 所以当我通过输入值进行搜索时,比如说101。它将返回“富有”?如何在枚举中执行此操作?你能举个例子吗?我不想使用forloop循环整个枚举以获取字符串_值。可能吗?是的,Oracle的教程向您展示了如何: 您要查找的是反向查找。需要在构造函数中接受密钥,并且需要查找方法 借用的一个例子是: 公共枚举财富级别{ 差(10),, 里奇(100), 非常富有(1000);
enum {
10 poor
100 rich
1000 very_rich
}
所以当我通过输入值进行搜索时,比如说101。它将返回“富有”?如何在枚举中执行此操作?你能举个例子吗?我不想使用forloop循环整个枚举以获取字符串_值。可能吗?是的,Oracle的教程向您展示了如何:
您要查找的是反向查找。需要在构造函数中接受密钥,并且需要查找方法 借用的一个例子是:
公共枚举财富级别{
差(10),,
里奇(100),
非常富有(1000);
私有静态最终映射查找
=新HashMap();
静止的{
for(WealthLevel w:EnumSet.allOf(WealthLevel.class))
lookup.put(w.getCode(),w);
}
私有整数码;
私人财富水平(整数代码){
this.code=代码;
}
public int getCode(){return code;}
公共静态财富水平获取(整数代码){
返回lookup.get(代码);
}
}
在java中,枚举是一个类。因此,您可以添加任何要检索值的方法。如果方法值不够,您可以使用任何其他方法来满足您的需求
也许您的问题也是关于向enum添加数据成员。你也可以这样做
enum A {
A(1),
B(2);
private int a;
A( int a) { this.a=a; }
A retrieve( int a )
{
Your code here maybe using a hashmap
}
}
“标准”方式
使用额外的成员变量(包含值10
、100
和1000
)创建enum
)。然后只需在enumgetWealth
中创建一个静态方法,根据money
参数查找正确的enum值:
static enum Wealth {
POOR(10), RICH(100), VERY_RICH(1000);
private final int money;
private Wealth(int money) {
this.money = money;
}
public static Wealth getWealth(int money) {
Wealth found = POOR;
for (Wealth w : values())
if (w.money <= money)
found = w;
return found;
}
}
public static void main(String[] args) {
System.out.println(Wealth.getWealth(101));
System.out.println(Wealth.getWealth(9));
System.out.println(Wealth.getWealth(10000));
}
static enum Wealth {
POOR, RICH, VERY_RICH; // 10, 100, 1000
public static Wealth getWealth(int money) {
int len = Integer.toString(money).length();
int ordinal = Math.max(0, Math.min(len - 2, values().length - 1));
return values()[ordinal];
}
}
无循环: 我在你的一条评论中看到,你希望不重复。这是可以做到的,但需要一些技巧。首先,在此解决方案(101001000)中不能更改您的值,因为它使用
money
参数给定的字符串长度:
static enum Wealth {
POOR(10), RICH(100), VERY_RICH(1000);
private final int money;
private Wealth(int money) {
this.money = money;
}
public static Wealth getWealth(int money) {
Wealth found = POOR;
for (Wealth w : values())
if (w.money <= money)
found = w;
return found;
}
}
public static void main(String[] args) {
System.out.println(Wealth.getWealth(101));
System.out.println(Wealth.getWealth(9));
System.out.println(Wealth.getWealth(10000));
}
static enum Wealth {
POOR, RICH, VERY_RICH; // 10, 100, 1000
public static Wealth getWealth(int money) {
int len = Integer.toString(money).length();
int ordinal = Math.max(0, Math.min(len - 2, values().length - 1));
return values()[ordinal];
}
}
这是一种既不优雅也不高效的方法,但你看不到任何循环 我从Chip的答案中偷取了一些基本的东西,并添加了一组:
public enum WealthLevel {
POOR(10),
RICH(100),
VERY_RICH(1000);
private static final Map<Integer,Status> lookup
= new HashMap<Integer,Status>();
// contains all codes ordered - for headSet call.
private static final SortedSet<Integer> intValues = new TreeSet<Integer>();
static {
for(WealthLevel w : EnumSet.allOf(WealthLevel.class)) {
lookup.put(w.getCode(), w);
intValues.add( w.getCode() );
}
}
private int code;
private WealthLevel(int code) {
this.code = code;
}
public int getCode() { return code; }
public static WealthLevel get(int code) {
if (lookup.contains(code)) {
return lookup.get(code);
}
// No visible iteration through performance probably is not great
SortedSet<Integer> lower = intValues.headSet(code);
if (lower.size() > 0) {
return lookup.get( lower.last() );
}
return null; // no possible value <= code
}
}
公共枚举财富级别{
差(10),,
里奇(100),
非常富有(1000);
私有静态最终映射查找
=新HashMap();
//包含订购的所有代码-用于耳机通话。
私有静态最终分类数据集intValues=新树集();
静止的{
for(WealthLevel w:EnumSet.allOf(WealthLevel.class)){
lookup.put(w.getCode(),w);
add(w.getCode());
}
}
私有整数码;
私人财富水平(整数代码){
this.code=代码;
}
public int getCode(){return code;}
公共静态财富水平获取(整数代码){
if(lookup.contains(代码)){
返回lookup.get(代码);
}
//没有通过性能进行可见的迭代可能不是很好
SortedSet lower=输入值。耳机(代码);
如果(较低的.size()>0){
返回lookup.get(lower.last());
}
return null;//没有可能的值使用带有值的enum
,其他人已经建议过了
然后,提供一个静态lookup(int)
方法,通过所有值的有序列表/数组执行搜索,而不是通过枚举值执行蛮力迭代搜索
要执行搜索,请以中位数或中间值作为“根”开始,并将我们要查找的值与该值进行比较
如果我们要查找的值正好是这个值,那么我们就完成了。如果值小于这个值,那么我们开始搜索值的下半部分,再次从中间开始搜索。如果值更大,则与它后面的值进行比较,看看它是否在范围内。如果值仍然较大,则在上半部分搜索,依此类推
编辑:按要求编写示例代码
public enum Wealth {
BROKE(0),
DESTITUTE(10),
POOR(100),
MIDDLE_CLASS(10000),
RICH(100000),
MILLIONAIRE(1000000),
BILLIONAIRE(1000000000);
private final int value;
private Wealth(final int value) {
this.value = value;
}
public final int getValue() {
return value;
}
/**
* @param v
* the value we're looking for
* @return Wealth
*/
public static Wealth lookup(final int v) {
final Wealth[] a = Wealth.values();
int min = 0;
int max = a.length - 1;
int i;
do {
i = (min + max) / 2;
final int av = a[i].value;
if (v < av) {
max = i;
} else if (v > av) {
if (i + 1 < a.length && v < a[i + 1].value) {
break;
}
min = i + 1;
}
} while (v != a[i].value && min < max);
if (min == max) {
return a[max];
}
return a[i];
}
}
公共枚举财富{
破产(0),
贫困的(10),
差(100),,
中产阶级(10000人),
富人(100000人),
百万富翁(1000000),
亿万富翁(100000000);
私有最终整数值;
私人财富(最终整数值){
这个值=值;
}
公共最终整数getValue(){
返回值;
}
/**
*@param v
*我们正在寻找的价值
*@还财
*/
公共静态财富查找(最终整数v){
最终财富[]a=财富价值();
int min=0;
int max=a.长度-1;
int i;
做{
i=(最小+最大)/2;
最终int av=a[i]。值;
if(vav){
if(i+1
几点注意:
这假设财富的值已经排序。否则,快速排序(双关语!)就可以了
这可能不是最有效的实现,只是根据维基百科上的伪代码改编的一个快速而肮脏的实现
如果您的值少于,比如说,十几个,那么线性搜索可能仍然比二进制搜索更有效(代码显然更容易解释)。只有当您有几十个或数百个值,并且执行了数百万次的查找时,二进制搜索才会真正获得回报
考虑到您的原始值,这是一种邪恶的、过早的优化。我只是想为那些处理大型值集的人提供一个选项。如果它必须是一个枚举,并且查找必须是O(log n),并且开销最小:
public enum WealthLevel {
POOR(10), RICH(100), VERY_RICH(1000);
private int lowerLimit;
private WealthLevel(int lowerLimit) {
this.lowerLimit = lowerLimit;
}
// cache for the sake of performance
private static final WealthLevel[] values = values();
private final static int[] lowerLimits;
static {
lowerLimits = new int[values.length];
for (int i = 0; i < values.length; i++) {
lowerLimits[i] = values[i].lowerLimit;
}
}
public static WealthLevel lookup(int wealth) {
int i = Arrays.binarySearch(lowerLimits, wealth);
if (i < 0) {
i = -i - 2;
}
return values[i];
}
}
公共枚举财富级别{
穷人(10人),富人(100人),非常富有(1000人);
洛厄利米特私人酒店;
私人财富水平(整数下限){
this.lowerLimit=lowerLimit;
}
//为了性能而缓存
私有静态最终财富水平[]值=值();
私有最终静态int[]lowerLimits;
静止的{
lowerLimits=新整数[values.length];
public enum WealthLevel {
POOR(10), RICH(100), VERY_RICH(1000);
private int lowerLimit;
private WealthLevel(int lowerLimit) {
this.lowerLimit = lowerLimit;
}
// cache for the sake of performance
private static final WealthLevel[] values = values();
private final static int[] lowerLimits;
static {
lowerLimits = new int[values.length];
for (int i = 0; i < values.length; i++) {
lowerLimits[i] = values[i].lowerLimit;
}
}
public static WealthLevel lookup(int wealth) {
int i = Arrays.binarySearch(lowerLimits, wealth);
if (i < 0) {
i = -i - 2;
}
return values[i];
}
}
class WealthConverter {
NavigableMap<Integer, String> levels = new TreeMap<Integer, String>();
{
levels.put(0, "pennyless");
levels.put(10, "poor");
levels.put(100, "rich");
levels.put(1000, "very rich");
}
public String lookup(int wealth) {
return levels.floorEntry(wealth).getValue();
}
}