Recently I was reviewing one PR raised by team memeber and going through one utitlity method and found out there are too many muatable variable roaming aroung in the code which I didn't like, So thought to convert in Funtional way,
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
public class MultipleIPAddressCal {
private MultipleIPAddressCal() {}
public static String getAllIpAddresses() {
StringBuilder allIPAddress = new StringBuilder();
String allIPAddressAppended = null;
try{
Enumeration<networkinterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = interfaces.nextElement();
if (!networkInterface.isUp()) {
continue;
}
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
int npf = interfaceAddress.getNetworkPrefixLength();
InetAddress address = interfaceAddress.getAddress();
allIPAddress.append(address.getHostAddress()).append(";");
}
}
int lastSemiColon = allIPAddress.lastIndexOf(";");
allIPAddressAppended = allIPAddress.substring(0,lastSemiColon);
} catch (Exception ex){
log.error(ex.getMessage());
}
return allIPAddressAppended;
}
}
Let's convert this code to functional way So it will be less cluttered.
import org.apache.commons.lang3.StringUtils;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.Spliterator;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class MultipleIPAddressCal {
private MultipleIPAddressCal() {
}
public static String getAllIpAddresses() {
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
EnumerationSpliterator<NetworkInterface> spliterator
= new EnumerationSpliterator<NetworkInterface>(Long.MAX_VALUE, Spliterator.ORDERED, interfaces);
return StreamSupport.stream(spliterator, false)
.flatMap(networkInterface -> networkInterface.getInterfaceAddresses()
.stream()
.map(MultipleIPAddressCal::extractIPV6address))
.collect(Collectors.joining(";"));
} catch (Exception ex) {
log.error(ex.getMessage());
return StringUtils.EMPTY;
}
}
private static String extractIPV6address(InterfaceAddress interfaceAddress) {
InetAddress address = interfaceAddress.getAddress();
if (address.getHostAddress().lastIndexOf("%") != -1) {
return address.getHostAddress().substring(0, address.getHostAddress().lastIndexOf("%"));
} else {
return address.getHostAddress();
}
}
}
To convert Enumeration into stream you need SplitIterator on it.
import java.util.Enumeration;
import java.util.Spliterators;
import java.util.function.Consumer;
public class EnumerationSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
private final Enumeration<T> enumeration;
public EnumerationSpliterator(long est, int additionalCharacteristics, Enumeration<T> enumeration) {
super(est, additionalCharacteristics);
this.enumeration = enumeration;
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
if (enumeration.hasMoreElements()) {
action.accept(enumeration.nextElement());
return true;
}
return false;
}
@Override
public void forEachRemaining(Consumer<? super T> action) {
while (enumeration.hasMoreElements())
action.accept(enumeration.nextElement());
}
}