从java中的List中随机选择一个对象

时间:2014-06-16 08:23:01

标签: java list object random

在你开始给这个问题-1之前,我想说我已经阅读了至少4个关于这类问题的问题,但是他们每个人都没有完全帮助我。

我有这个类,它包含以下方法:

class OperationDispatcher {

    OperationDispatcher(ManagementService.Client managementClient) {
        this.managementClient = managementClient;
    }

    ManagementService.Client managementClient;

    public long executeOperation(String opName, int num1, int num2) throws TException {

        List<ServiceProvider> providers = new ArrayList<ServiceProvider>();
        providers = managementClient.getProvidersForService(opName);

        long result = 0;

        if(providers.isEmpty())
            System.out.println("No Service Available");
        else
            switch(opName) {
                case "addition":
                    result = arithmeticClient.add(num1, num2);
                    break;
                case "multiplication":
                    result = arithmeticClient.multiply(num1, num2);
                    break;
                case "substraction":
                    result = arithmeticClient.substract(num1, num2);
                    break;
                case "division":
                    result = arithmeticClient.divide(num1, num2);
                    break;  
        }   
        return result;
    }

}

我试图实现这种行为:

  1. 两个或多个对象“节点”注册到我在我的测试中创建的本地中央服务器;
  2. 每个节点都有一个服务列表,并向OR提出请求,为其他节点提供服务;
  3. 当发出请求时,返回“ServiceProviders”列表,其中每一个都是可能的“应答节点”;
  4. 从列表中选择随机ServiceProvider;
  5. 所选的ServiceProvider执行请求的算术运算。
  6. 我对第1,2,3和5点没有任何问题。我现在正在尝试修改方法,使其在列表中的选项中选择一个随机的ServiceProvider。

    我不确定(在我班上)我应该把代码从列表中随机挑选并随后执行所请求的操作。你能救我吗?

    编辑所以,我修改了我的代码如下:

    class OperationDispatcher {
    
        private List<ServiceProvider> providers = new ArrayList<ServiceProvider>();
    
        OperationDispatcher(ManagementService.Client managementClient) {
            this.managementClient = managementClient;
        }
    
        //tiro su un management client
        ManagementService.Client managementClient;
    
        public long executeOperation(String opName, int num1, int num2) throws TException {
    
            ServiceProvider randomProvider = new ServiceProvider();
            providers = managementClient.getProvidersForService(opName);
    
            long result = 0;
    
            if(providers.isEmpty())
                System.out.println("No Service Available");
    
            else if(providers.size() == 1) {
                switch(opName) {
                    case "addition":
                        result = arithmeticClient.add(num1, num2);
                        break;
                    case "multiplication":
                        result = arithmeticClient.multiply(num1, num2);
                        break;
                    case "substraction":
                        result = arithmeticClient.substract(num1, num2);
                        break;
                    case "division":
                        result = arithmeticClient.divide(num1, num2);
                        break;
                }
            }
    
            else if (providers.size() >= 2) {
                randomProvider = providers.get(random.nextInt(providers.size()));
                if(randomProvider != null) {
                    switch(opName) {
                    case "addition":
                        result = arithmeticClient.add(num1, num2);
                        break;
                    case "multiplication":
                        result = arithmeticClient.multiply(num1, num2);
                        break;
                    case "substraction":
                        result = arithmeticClient.substract(num1, num2);
                        break;
                    case "division":
                        result = arithmeticClient.divide(num1, num2);
                        break;
                    }
                }
            }
            return result;
        }
    
    }
    

    我的测试是这样的:

    @Before
    public void initializeManagementServer() throws Exception {
    
        managementServer = new ManagementServer(7911);
        managementServer.start();
    
        Thread.sleep(200);
        managementServerTransport = new TSocket("localhost", 7911);
        managementServerProtocol = new TBinaryProtocol(managementServerTransport);
        managementClient = new ManagementService.Client(managementServerProtocol);
        managementServerTransport.open();
    }
    
    @Test
    public void testArithmeticServer() throws Exception {
    
        ServiceProvider randomProvider = new ServiceProvider();
    
        List<String> node1Svc = new ArrayList<>();
        node1Svc.add("addition");
    
        List<String> node2Svc = new ArrayList<>();
        node2Svc.add("substraction");
        node2Svc.add("multiplication");
    
        List<String> node3Svc = new ArrayList<>();
        node3Svc.add("addition");
        node3Svc.add("multiplication");
        node3Svc.add("division");
    
        List<String> node4Svc = new ArrayList<>();
        node4Svc.add("addition");
        node4Svc.add("division");
    
        NodeManifest node1 = new NodeManifest("Node 1", node1Svc);
        NodeManifest node2 = new NodeManifest("Node 2", node2Svc);
        NodeManifest node3 = new NodeManifest("Node 3", node3Svc);
        NodeManifest node4 = new NodeManifest("Node 4", node4Svc);
    
        int port = managementClient.registerNode(node1);
        assertEquals(1026, port);
        port = managementClient.registerNode(node2);
        assertEquals(1027, port);
        port = managementClient.registerNode(node3);
        assertEquals(1028, port);
        port = managementClient.registerNode(node4);
        assertEquals(1029, port);
    
    
    
        arithmeticServer = new ArithmeticServer(port);
        arithmeticServer.start();
    
        arithmeticTransport = new TSocket("localhost", port);
        arithmeticProtocol = new TBinaryProtocol(arithmeticTransport);
        arithmeticClient = new ArithmeticService.Client(arithmeticProtocol);
        arithmeticTransport.open();
    
        OperationDispatcher dispatcher = new OperationDispatcher(managementClient);
        long result = dispatcher.executeOperation("addition", 1, 2);
        assertEquals(3, result);
        assertEquals(3, dispatcher.providers.size());
    
        arithmeticTransport.close();
        arithmeticServer.stop();
    
    @After
    public void teardownManagementServer() throws Exception {
        managementServerTransport.close();
        managementServer.stop();            
    }
    }
    

    我已经注册了4个节点。节点#1是要求服务“添加”的节点,节点#2#3和#4都具有该服务。然后我创建一个对象OperationDispatcher,询问服务“添加”,并返回一个包含三个ServiceProviders的列表。现在我想从该列表中随机选择一个项目,最后ServiceProvider执行该操作。现在,总是选择节点4。怎么了?

3 个答案:

答案 0 :(得分:4)

您可以使用Java的Random类,如下所示:

ServiceProvider provider = providers.get(new Random().nextInt(providers.size()));

请注意,初始化新的Random对象是一个稍微昂贵的操作,因此您可能希望创建一次,然后继续重复使用它:

private static final Random RANDOM = new Random();

// ...

ServiceProvider provider = providers.get(RANDOM.nextInt(providers.size()));

答案 1 :(得分:0)

假设您有List个服务servicesList 现在做如下:

double ramdomVal = Math.random();
int size =servicesList.size();

int pos = (new Double(ramdomVal %size)).intValue();

Service service = servicesList.get(pos);

这样您将始终获得随机服务对象。

答案 2 :(得分:0)

我想到了另一个想法。如果你可以使用Collections api shuffle(List<?> list, Random rnd) 获得不同价值的机会可能会增加。 有关详细信息,请参阅文档: http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#shuffle(java.util.List,%20java.util.Random)