Java 如何从JSON数组中获取随机对象

Java 如何从JSON数组中获取随机对象,java,android,json,Java,Android,Json,这是JSONAray: "cows": [ { "age": 972, "name": "Betty" "status": "publish", "sticky": "pregnant" }, { "age": 977, "name"; "Kate" "status": "publish", "sticky": "heat" }, { "age":

这是JSONAray:

"cows": [
    {
      "age": 972,
      "name": "Betty"
      "status": "publish",
      "sticky": "pregnant"
    },
    {
      "age": 977,
      "name"; "Kate"
      "status": "publish",
      "sticky": "heat"
    },
    {
      "age": 959,
      "name": "Julie"
      "site_age": 63178480,
      "sticky": "Nursing"
    },
    ...
 }
它包含20个对象。我想要的是:从20个对象中随机抽取3个对象。三个人的年龄都不是一个确定的数字,比如说961岁

目前我正在做的是:

private void parseCowsReq(JSONObject array) {
         try {
             for (int i = 0; i < 3; i++) {
                 int randumNum = getRandomCow(array);
                 JSONObject jsonObject = array.getJSONObject(randumNum);
                 String cowName = jsonObject.getString("name");
                 String cowStatus = jsonObject.getString("status");
                 Log.d(TAG, "Cow name is " + cowName + "cow Status is " + cowStatus);
             }

         } catch (JSONException e) {
             e.printStackTrace();
         }
  }

  private int getRandomCow(JSONArray jsonArray) {
          int length = jsonArray.length();
          int[] array;
          array = new int[length-1];
          int rnd = new Random().nextInt(array.length);
          return array[rnd];
  }
private void parseCowsReq(JSONObject数组){
试一试{
对于(int i=0;i<3;i++){
int randumNum=getRandomCow(数组);
JSONObject JSONObject=array.getJSONObject(randumNum);
字符串cowName=jsonObject.getString(“名称”);
字符串cowStatus=jsonObject.getString(“状态”);
Log.d(标签,“奶牛名称为”+奶牛名称+”奶牛状态为“+奶牛状态);
}
}捕获(JSONException e){
e、 printStackTrace();
}
}
私有int getRandomCow(JSONArray JSONArray){
int length=jsonArray.length();
int[]数组;
数组=新整数[length-1];
int rnd=new Random().nextInt(array.length);
返回数组[rnd];
}
此代码存在许多问题

  • 我不知道如何确保物体对齐
    JSONObject-JSONObject=array.getJSONObject(randumNum)将不会有
    961岁
  • 得到的随机数始终为0

    请问你知道怎么做吗


  • 您可以通过以下方式进行操作:

    public ArrayList<Integer> getRandomObject(JSONArray jsonArray, int indexesWeeNeed){
        Random rn = new Random();
        Set<Integer> generated = new LinkedHashSet<>();
        while(generated.size() < indexesWeeNeed){
            int index = rn.nextInt(10);
            JSONObject jsonObject = (JSONObject) jsonArray.get(index);
            int age = jsonObject.getInt("age");
            if(age<961) {
                generated.add(index);
            }
        }
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.addAll(generated);
        return arrayList;
    }
    
    public ArrayList getRandomObject(JSONArray-JSONArray,int-indexesweened){
    Random rn=新的Random();
    生成的集合=新LinkedHashSet();
    while(生成的.size()如果(年龄你可以这样做:

    public ArrayList<Integer> getRandomObject(JSONArray jsonArray, int indexesWeeNeed){
        Random rn = new Random();
        Set<Integer> generated = new LinkedHashSet<>();
        while(generated.size() < indexesWeeNeed){
            int index = rn.nextInt(10);
            JSONObject jsonObject = (JSONObject) jsonArray.get(index);
            int age = jsonObject.getInt("age");
            if(age<961) {
                generated.add(index);
            }
        }
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.addAll(generated);
        return arrayList;
    }
    
    public ArrayList getRandomObject(JSONArray-JSONArray,int-indexesweened){
    Random rn=新的Random();
    生成的集合=新LinkedHashSet();
    while(生成的.size()如果(年龄良好,首先加载对象:

    JSONArray array = /* your array */;
    
    接下来,我们需要一个方法从
    JSONArray
    (实际上是一个
    列表
    )中检索3个唯一的对象。让我们洗牌json数组的索引,这样我们就不必重复生成重复项:

    public Stream<JSONObject> randomObjects(JSONArray array, int amount) {
        if (amount > array.size()) {
            //error out, null, return array, whatever you desire
            return array;
        }
        List<Integer> indexes = IntStream.range(0, array.size()).collect(Collectors.toList());
        //random, but less time generating them and keeping track of duplicates
        Collections.shuffle(indexes);
        Set<Integer> back = new HashSet<>();
        Iterator<Integer> itr = indexes.iterator();
        while (back.size() < amount && itr.hasNext()) {
            int val = itr.next();
            if (array.get(val).getInt("age") != 961) { //or any other predicates
                back.add(val);
            }
        }
        return back.stream().map(array::get);
    }
    
    当我说“或任何其他谓词时,您也可以通过以下方法传递它们:

    public Stream<JSONObject> randomObjects(..., Predicate<Integer> validObject) {
        //...
        int val = itr.next();
        if (validObject.test(val)) {
            back.add(val);
        }
        //...
    }
    
    公共流随机对象(…,谓词validObject){
    //...
    int val=itr.next();
    if(有效对象测试(val)){
    返回。添加(val);
    }
    //...
    }
    
    这意味着您可以更改每个方法调用的黑名单:

    Stream<JSONObject> random = randomObjects(array, 3, val -> array.get(val).getInt("age") != 961);
    
    Stream random=randomObjects(数组,3,val->array.get(val).getInt(“年龄”)!=961);
    
    首先,加载对象:

    JSONArray array = /* your array */;
    
    接下来,我们需要一个方法从
    JSONArray
    (实际上是一个
    列表
    )中检索3个唯一的对象。让我们洗牌json数组的索引,这样我们就不必重复生成重复项:

    public Stream<JSONObject> randomObjects(JSONArray array, int amount) {
        if (amount > array.size()) {
            //error out, null, return array, whatever you desire
            return array;
        }
        List<Integer> indexes = IntStream.range(0, array.size()).collect(Collectors.toList());
        //random, but less time generating them and keeping track of duplicates
        Collections.shuffle(indexes);
        Set<Integer> back = new HashSet<>();
        Iterator<Integer> itr = indexes.iterator();
        while (back.size() < amount && itr.hasNext()) {
            int val = itr.next();
            if (array.get(val).getInt("age") != 961) { //or any other predicates
                back.add(val);
            }
        }
        return back.stream().map(array::get);
    }
    
    当我说“或任何其他谓词时,您也可以通过以下方法传递它们:

    public Stream<JSONObject> randomObjects(..., Predicate<Integer> validObject) {
        //...
        int val = itr.next();
        if (validObject.test(val)) {
            back.add(val);
        }
        //...
    }
    
    公共流随机对象(…,谓词validObject){
    //...
    int val=itr.next();
    if(有效对象测试(val)){
    返回。添加(val);
    }
    //...
    }
    
    这意味着您可以更改每个方法调用的黑名单:

    Stream<JSONObject> random = randomObjects(array, 3, val -> array.get(val).getInt("age") != 961);
    
    Stream random=randomObjects(数组,3,val->array.get(val).getInt(“年龄”)!=961);
    
    有一个地方很糟糕,那就是你打电话的时候
    Random().nextInt(array.length);
    array.length是您刚刚创建的新数组。您需要在现有数组上执行以下功能:
    Random().nextInt(jsonArray)
    获取除零以外的随机数。


    至于确保您没有获得特定的年龄,我建议分解代码,不要在for循环中调用getRandomCow(数组)函数。检索cow时,检查名称是否匹配,检查年龄,如果有效,则保留它。如果没有,则获取另一个cow。

    一个混乱的部分是在调用cow时
    Random().nextInt(array.length);
    array.length是您刚刚创建的新数组。您需要在现有数组上执行以下功能:
    Random().nextInt(jsonArray)
    获取除零以外的随机数。


    至于确保您没有达到特定的年龄,我建议将代码分解为不调用getRandomCow(数组)函数位于for循环内部。当您检索一头牛时,检查名称不匹配,检查年龄,如果它有效,则保留它。如果不能获取另一头牛。

    谢谢。
    randomNum=I;
    您的实际意思是
    String randomNum=I;
    ,对吗?如果是,结果为我提供了-14,它打印了这个
    org.json.JSONException:Index-14超出logcat中的范围[0..20)
    。最后一个问题是,如果随机数是20,它会抛出一个JSONException。在JSONArray中,数组从0开始。因此在这种情况下,将没有第20项,而是有0-19项。但是在第
    int randomNum=rn.nextInt(JSONArray.length+1)行中
    我把
    +
    改成了
    -
    ,我没有遇到任何问题。但是你怎么看?很抱歉,我错误地发布了一条未完成的评论。现在已经完成了。不,不要这样做,只使用我发布的评论。删除
    +1
    @Ozufok。但这可能会返回一个20的数字,对吗?另外,它返回了一个相同的数字数字两次。抱歉打扰你。谢谢。在第
    randomNum=I;
    行中,你实际上是指
    String randomNum=I;
    ,对吗?如果是,结果是-14,它打印了这个
    org.json.JSONException:Index-14超出范围[0..20)
    在logcat中。最后一个问题是,如果随机数是20,它会抛出一个JSONException。在JSONArray中,数组从0开始。因此在这种情况下,将没有第20项,而不是第20项