Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java枚举按数字范围搜索_Java_Enums - Fatal编程技术网

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
)。然后只需在enum
getWealth
中创建一个静态方法,根据
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();
    }
}