I have a builder pattern in which I am taking few parameters from the customer and basis on that I am building my builder class and then that builder class is passed to our underlying library and then my library will use it.
public final class KeyHolder {
  private final String clientId;
  private final String deviceId;
  private final int processId;
  private final Cache<String, List<Response>> userCache;
  private static final long MAXIMUM_CACHE_SIZE = 5000000;
  private static final long EXPIRE_AFTER_WRITE = 120; // this is in seconds
  private KeyHolder(Builder builder) {
    this.clientId = builder.clientId;
    this.deviceId = builder.deviceId;
    this.processId = builder.processId;
    this.maximumCacheSize = builder.maximumCacheSize;
    this.expireAfterWrite = builder.expireAfterWrite;
    // how to execute this line only once
    this.userCache =
        CacheBuilder
            .newBuilder()
            .maximumSize(maximumCacheSize)
            .expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS)
            .removalListener(
                RemovalListeners.asynchronous(new CustomListener(),
                    Executors.newSingleThreadScheduledExecutor())).build();
  }
  public static class Builder {
    protected final int processId;
    protected String clientId = null;
    protected String deviceId = null;
    protected long maximumCacheSize = MAXIMUM_CACHE_SIZE;
    protected long expireAfterWrite = EXPIRE_AFTER_WRITE;
    public Builder(int processId) {
      this.processId = processId;
    }
    public Builder setClientId(String clientId) {
      this.clientId = clientId;
      return this;
    }
    public Builder setDeviceId(String deviceId) {
      this.deviceId = deviceId;
      return this;
    }
    public Builder setMaximumCacheSize(long size) {
      this.maximumCacheSize = size;
      return this;
    }
    public Builder setExpiryTimeAfterWrite(long duration) {
      this.expireAfterWrite = duration;
      return this;
    }
    public KeyHolder build() {
      return new KeyHolder(this);
    }
  }
 // getters here
}
For each and every call to our library they create a new KeyHolder builder class everytime and pass it to our library. processId, clientId, deviceId will change with every call but maximumCacheSize and expireAfterWrite will stay same as it with every call. As you can see above, I am using guava cache here and since they are creating KeyHolder builder class everytime how can I make sure that the below line is executed only once in my constructor?
    this.userCache =
        CacheBuilder
            .newBuilder()
            .maximumSize(maximumCacheSize)
            .expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS)
            .removalListener(
                RemovalListeners.asynchronous(new CustomListener(),
                    Executors.newSingleThreadScheduledExecutor())).build();
Since with the current code right now, it will get executed with every call and I will get a new guava cache every time in my library so whatever entry was cached earlier within my library by using this guava cache will get lost.
How to initialize a particular variable only once and after that it should ignore the value whatever is being passed to it?
Update:
public class DataClient implements Client {
    private final ExecutorService executor = Executors.newFixedThreadPool(10);
    // for synchronous call
    @Override
    public List<Response> executeSync(KeyHolder key) {
        Cache<String, List<Response>> userCache = key.getUserCache();
        List<Response> response = userCache.getIfPresent(key.getUUID());
        if (CollectionUtils.isNotEmpty(response)) {
          return response;
        }
        // if not in cache, then normally call the flow and populate the cache
        List<Response> dataResponse = null;
        Future<List<Response>> future = null;
        try {
            future = executeAsync(key);
            dataResponse = future.get(key.getTimeout(), TimeUnit.MILLISECONDS);
            userCache.put(key.getUUID(), dataResponse);
        } catch (TimeoutException ex) {
            // log error and return DataResponse
        } catch (Exception ex) {
            // log error and return DataResponse
        }
        return dataResponse;
    }
}
 
     
     
     
    