简体   繁体   中英

Split ArrayList based on word

Attempting (and failing) to split an ArrayList based on a 'start word'.

The ArrayList is a collection of sockets, originally a HashSet -

[[Socket[addr=/192.168.150.210,port=2001,localport=49671], Socket[addr=/192.168.150.211,port=2001,localport=49670], Socket[addr=/192.168.150.215,port=2001,localport=49672], Socket[addr=/192.168.150.213,port=10001,localport=49669]]]

In need to somehow split that array so I end up with a new ArrayList that then contains distinct elements (each beginning Socket[ etc so I can then iterate through (based on size) looking for a matching IP address.

ie (as 4 'records')

Socket[addr=/192.168.150.210,port=2001,localport=49671]
Socket[addr=/192.168.150.211,port=2001,localport=49670]
Socket[addr=/192.168.150.215,port=2001,localport=49672]
Socket[addr=/192.168.150.213,port=10001,localport=49669]

I cant use for i = on the original ArrayList because its size is 1 record ( need 4 records)

ie

Object currentSock = null; 

for (int i =0; i<  theseSocks.size(); i++)
{
currentSock = theseSocks.get(i);
if (currentSock.toString().contains(ipAddress))
{
System.out.println(" the ArrayList element is " +currentSock);
break;
}
}

Thoughts appreciated (I am a newbie). Regards Ralph

Generally, it's better practice not to filter or find by generating a string representing the entire object. Match based on the property of interest instead, which in your case is the IP address.

In Java 8 and beyond, there is a feature called streams that makes this very quick.

In this case, I'm still using the inetAddress toString to string match the IP, but not calling toString on the whole object.

The line of interest looks like this:

Optional< Socket > matchingSocket = sockets.stream().findAny().filter( socket -> socket.getInetAddress().toString().equals( "/192.168.0.1" ) );

A runnable example follows. You need the targets to actually connect, or you will get dropped into the exception handling. So you need to find computers willing to accept connections on a port and change the add lines accordingly, or use your live HashSet.

try
{
    List< Socket > sockets = Lists.newArrayList( );
    sockets.add( new Socket( "192.168.0.1", 7777 ) );
    sockets.add( new Socket( "192.168.0.2", 7777 ) );

    Optional< Socket > matchingSocket = sockets.stream().findAny().filter( socket -> socket.getInetAddress().toString().equals( "/192.168.0.1" ) );

}
catch( Exception e )
{
    //handle this
}

Here is an example using a for loop instead of streams:

try
{
    List< Socket > sockets = Lists.newArrayList( );
    sockets.add( new Socket( "192.168.0.1", 7777 ) );
    sockets.add( new Socket( "192.168.0.2", 7777 ) );

    for( Socket socket : sockets)
    {
        if( socket.getInetAddress().toString().equals( "/192.168.0.1" ) )
            System.out.println( "Found socket " + socket.toString() );
    }

}
catch( Exception e )
{
    //handle this
}

Also worth noting this exact same for loop works with your HashSet. I'm wondering if your ArrayList somehow contains a single entry of the HashSet instead of individual sockets. You could just iterate the HashSet instead.

Replace my arraylist lines with the following to test:

Set< Socket > sockets = Sets.newHashSet( );
sockets.add( new Socket( "192.168.0.1", 7777 ) );
sockets.add( new Socket( "192.168.0.2", 7777 ) );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM