convert ImmutableList to unmodifiable list

This converts all remaining instances of ImmutableList (except those
in core tests) to JDK unmodifiable list.
This commit is contained in:
Sean Gilligan 2022-03-26 13:22:17 -07:00 committed by Andreas Schildbach
parent 6d7dd7919f
commit 1343776286
16 changed files with 70 additions and 57 deletions

View file

@ -19,7 +19,6 @@ package org.bitcoinj.core;
import com.google.common.annotations.*;
import com.google.common.base.*;
import com.google.common.collect.*;
import org.bitcoinj.params.AbstractBitcoinNetParams;
import org.bitcoinj.script.*;
import org.slf4j.*;
@ -915,10 +914,10 @@ public class Block extends Message {
this.hash = null;
}
/** Returns an immutable list of transactions held in this block, or null if this object represents just a header. */
/** Returns an unmodifiable list of transactions held in this block, or null if this object represents just a header. */
@Nullable
public List<Transaction> getTransactions() {
return transactions == null ? null : ImmutableList.copyOf(transactions);
return transactions == null ? null : Collections.unmodifiableList(transactions);
}
// ///////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -16,32 +16,40 @@
package org.bitcoinj.core;
import com.google.common.collect.ImmutableList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Represents Block Locator in GetBlocks and GetHeaders messages
**/
public final class BlockLocator {
private final ImmutableList<Sha256Hash> hashes;
private final List<Sha256Hash> hashes; // unmodifiable list
public BlockLocator() {
hashes = ImmutableList.of();
hashes = Collections.emptyList();
}
/**
* Creates a Block locator with defined list of hashes.
*/
public BlockLocator(ImmutableList<Sha256Hash> hashes) {
this.hashes = hashes;
public BlockLocator(List<Sha256Hash> hashes) {
this.hashes = Collections.unmodifiableList(hashes);
}
// Create a new BlockLocator by copying an instance and appending an element
private BlockLocator(BlockLocator old, Sha256Hash hashToAdd) {
this(Stream.concat(old.hashes.stream(), Stream.of(hashToAdd))
.collect(Collectors.toList())
);
}
/**
* Add a {@link Sha256Hash} to a newly created block locator.
*/
public BlockLocator add(Sha256Hash hash) {
return new BlockLocator(new ImmutableList.Builder<Sha256Hash>().addAll(this.hashes).add(hash).build());
return new BlockLocator(this, hash);
}
/**

View file

@ -1247,7 +1247,7 @@ public class PeerGroup implements TransactionBroadcaster {
if ((chain != null && chain.shouldVerifyTransactions()) || !vBloomFilteringEnabled)
return;
// We only ever call bloomFilterMerger.calculate on jobQueue, so we cannot be calculating two filters at once.
FilterMerger.Result result = bloomFilterMerger.calculate(ImmutableList.copyOf(peerFilterProviders /* COW */));
FilterMerger.Result result = bloomFilterMerger.calculate(Collections.unmodifiableList(peerFilterProviders /* COW */));
boolean send;
switch (mode) {
case SEND_IF_CHANGED:

View file

@ -34,9 +34,9 @@ import java.util.List;
* {@code HDPath} is immutable and uses the {@code Collections.UnmodifiableList} type internally.
* <p>
* It implements {@code java.util.List<ChildNumber>} to ease migration
* from the previous Guava {@code ImmutableList<ChildNumber>}. It should be a minor breaking change
* to replace {@code ImmutableList<ChildNumber>} with {@code List<ChildNumber>} where necessary in your code. Although
* it is recommended to use the {@code HDPath} type for clarity and for access to {@code HDPath}-specific functionality.
* from the previous implementation. When an {@code HDPath} is returned you can treat it as a {@code List<ChildNumber>}
* where necessary in your code. Although it is recommended to use the {@code HDPath} type for clarity and for
* access to {@code HDPath}-specific functionality.
* <p>
* Take note of the overloaded factory methods {@link HDPath#M()} and {@link HDPath#m()}. These can be used to very
* concisely create HDPath objects (especially when statically imported.)

View file

@ -17,7 +17,6 @@
package org.bitcoinj.kits;
import com.google.common.collect.*;
import com.google.common.io.Closeables;
import com.google.common.util.concurrent.AbstractIdleService;
import org.bitcoinj.core.listeners.*;
@ -241,7 +240,7 @@ public class WalletAppKit extends AbstractIdleService {
* initialized/started.</p>
*/
protected List<WalletExtension> provideWalletExtensions() throws Exception {
return ImmutableList.of();
return Collections.emptyList();
}
/**

View file

@ -18,10 +18,11 @@ package org.bitcoinj.net;
import org.bitcoinj.core.BloomFilter;
import org.bitcoinj.core.PeerFilterProvider;
import com.google.common.collect.ImmutableList;
import org.bitcoinj.core.PeerGroup;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
// This code is unit tested by the PeerGroup tests.
@ -55,7 +56,8 @@ public class FilterMerger {
public boolean changed;
}
public Result calculate(ImmutableList<PeerFilterProvider> providers) {
public Result calculate(List<PeerFilterProvider> providerList) {
List<PeerFilterProvider> providers = Collections.unmodifiableList(providerList);
LinkedList<PeerFilterProvider> begunProviders = new LinkedList<>();
try {
// All providers must be in a consistent, unchanging state because the filter is a merged one that's

View file

@ -22,7 +22,6 @@ import org.bitcoinj.crypto.X509Utils;
import org.bitcoinj.script.ScriptBuilder;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import org.bitcoin.protocols.payments.Protos;
@ -33,6 +32,7 @@ import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@ -67,7 +67,7 @@ public class PaymentProtocol {
public static Protos.PaymentRequest.Builder createPaymentRequest(NetworkParameters params,
@Nullable Coin amount, Address toAddress, @Nullable String memo, @Nullable String paymentUrl,
@Nullable byte[] merchantData) {
return createPaymentRequest(params, ImmutableList.of(createPayToAddressOutput(amount, toAddress)), memo,
return createPaymentRequest(params, Collections.singletonList(createPayToAddressOutput(amount, toAddress)), memo,
paymentUrl, merchantData);
}
@ -289,7 +289,7 @@ public class PaymentProtocol {
if (refundAmount == null)
throw new IllegalArgumentException("Specify refund amount if refund address is specified.");
return createPaymentMessage(transactions,
ImmutableList.of(createPayToAddressOutput(refundAmount, refundAddress)), memo, merchantData);
Collections.singletonList(createPayToAddressOutput(refundAmount, refundAddress)), memo, merchantData);
} else {
return createPaymentMessage(transactions, null, memo, merchantData);
}

View file

@ -17,7 +17,6 @@
package org.bitcoinj.utils;
import static org.bitcoinj.core.Coin.SMALLEST_UNIT_EXPONENT;
import com.google.common.collect.ImmutableList;
import java.math.BigInteger;
import static java.math.BigDecimal.ONE;
@ -29,6 +28,7 @@ import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Collections;
import java.util.Locale;
/**
@ -109,7 +109,7 @@ public final class BtcAutoFormat extends BtcFormat {
/** Constructor */
protected BtcAutoFormat(Locale locale, Style style, int fractionPlaces) {
super((DecimalFormat)NumberFormat.getCurrencyInstance(locale), fractionPlaces, ImmutableList.<Integer>of());
super((DecimalFormat)NumberFormat.getCurrencyInstance(locale), fractionPlaces, Collections.emptyList());
style.apply(this.numberFormat);
}

View file

@ -20,8 +20,10 @@ import org.bitcoinj.utils.BtcAutoFormat.Style;
import static org.bitcoinj.utils.BtcAutoFormat.Style.*;
import org.bitcoinj.core.Coin;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import com.google.common.collect.ImmutableList;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.base.Strings;
@ -1235,11 +1237,13 @@ public abstract class BtcFormat extends Format {
/** Sets the number of fractional decimal places to be displayed on the given
* NumberFormat object to the value of the given integer.
* @return The minimum and maximum fractional places settings that the
* formatter had before this change, as an ImmutableList. */
private static ImmutableList<Integer> setFormatterDigits(DecimalFormat formatter, int min, int max) {
ImmutableList<Integer> ante = ImmutableList.of(
formatter.getMinimumFractionDigits(),
formatter.getMaximumFractionDigits()
* formatter had before this change, as an unmodifiable List. */
private static List<Integer> setFormatterDigits(DecimalFormat formatter, int min, int max) {
List<Integer> ante = Collections.unmodifiableList(
Arrays.asList(
formatter.getMinimumFractionDigits(),
formatter.getMaximumFractionDigits()
)
);
formatter.setMinimumFractionDigits(min);
formatter.setMaximumFractionDigits(max);

View file

@ -25,7 +25,6 @@ import org.bitcoinj.utils.ListenerRegistration;
import org.bitcoinj.utils.Threading;
import org.bitcoinj.wallet.listeners.KeyChainEventListener;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.ByteString;
import org.bouncycastle.crypto.params.KeyParameter;
@ -84,7 +83,7 @@ public class BasicKeyChain implements EncryptableKeyChain {
checkState(keyCrypter == null); // We will refuse to encrypt an empty key chain.
final ECKey key = new ECKey();
importKeyLocked(key);
queueOnKeysAdded(ImmutableList.of(key));
queueOnKeysAdded(Collections.singletonList(key));
}
return hashToKeys.values().iterator().next();
} finally {
@ -105,7 +104,7 @@ public class BasicKeyChain implements EncryptableKeyChain {
keys.add(new ECKey());
}
ImmutableList<ECKey> immutableKeys = ImmutableList.copyOf(keys);
List<ECKey> immutableKeys = Collections.unmodifiableList(keys);
importKeysLocked(immutableKeys);
queueOnKeysAdded(immutableKeys);
}
@ -133,7 +132,7 @@ public class BasicKeyChain implements EncryptableKeyChain {
}
public int importKeys(ECKey... keys) {
return importKeys(ImmutableList.copyOf(keys));
return importKeys(Collections.unmodifiableList(Arrays.asList(keys)));
}
public int importKeys(List<? extends ECKey> keys) {
@ -198,7 +197,7 @@ public class BasicKeyChain implements EncryptableKeyChain {
checkKeyEncryptionStateMatches(key);
if (hasKey(key)) return;
importKeyLocked(key);
queueOnKeysAdded(ImmutableList.of(key));
queueOnKeysAdded(Collections.singletonList(key));
} finally {
lock.unlock();
}

View file

@ -28,7 +28,6 @@ import org.bitcoinj.wallet.listeners.KeyChainEventListener;
import com.google.common.base.MoreObjects;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
import com.google.protobuf.ByteString;
@ -1310,14 +1309,14 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
* Returns leaf keys issued by this chain (including lookahead zone)
*/
public List<DeterministicKey> getLeafKeys() {
ImmutableList.Builder<DeterministicKey> keys = ImmutableList.builder();
List<DeterministicKey> keys = new ArrayList<>();
for (ECKey key : getKeys(true, false)) {
DeterministicKey dKey = (DeterministicKey) key;
if (dKey.getPath().size() == getAccountPath().size() + 2) {
keys.add(dKey);
}
}
return keys.build();
return Collections.unmodifiableList(keys);
}
/*package*/ static void serializeSeedEncryptableItem(DeterministicSeed seed, Protos.Key.Builder proto) {

View file

@ -447,7 +447,9 @@ public class KeyChainGroup implements KeyBag {
*/
public final DeterministicKeyChain getActiveKeyChain(Script.ScriptType outputScriptType, long keyRotationTimeSecs) {
checkState(isSupportsDeterministicChains(), "doesn't support deterministic chains");
for (DeterministicKeyChain chain : ImmutableList.copyOf(chains).reverse())
List<DeterministicKeyChain> chainsReversed = new ArrayList<>(chains);
Collections.reverse(chainsReversed);
for (DeterministicKeyChain chain : chainsReversed)
if (chain.getOutputScriptType() == outputScriptType
&& chain.getEarliestKeyCreationTime() >= keyRotationTimeSecs)
return chain;
@ -508,7 +510,7 @@ public class KeyChainGroup implements KeyBag {
/** Imports the given keys into the basic chain, creating it if necessary. */
public int importKeys(ECKey... keys) {
return importKeys(ImmutableList.copyOf(keys));
return importKeys(Collections.unmodifiableList(Arrays.asList(keys)));
}
public boolean checkPassword(CharSequence password) {

View file

@ -16,7 +16,6 @@
package org.bitcoinj.wallet;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.protobuf.ByteString;
@ -32,6 +31,7 @@ import org.bitcoinj.script.ScriptBuilder;
import org.bouncycastle.crypto.params.KeyParameter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -151,25 +151,26 @@ public class MarriedKeyChain extends DeterministicKeyChain {
@Override
public Script freshOutputScript(KeyPurpose purpose) {
DeterministicKey followedKey = getKey(purpose);
ImmutableList.Builder<ECKey> keys = ImmutableList.<ECKey>builder().add(followedKey);
List<ECKey> keys = new ArrayList<>();
keys.add(followedKey);
for (DeterministicKeyChain keyChain : followingKeyChains) {
DeterministicKey followingKey = keyChain.getKey(purpose);
checkState(followedKey.getChildNumber().equals(followingKey.getChildNumber()), "Following keychains should be in sync");
keys.add(followingKey);
}
List<ECKey> marriedKeys = keys.build();
List<ECKey> marriedKeys = Collections.unmodifiableList(keys);
Script redeemScript = ScriptBuilder.createRedeemScript(sigsRequiredToSpend, marriedKeys);
return ScriptBuilder.createP2SHOutputScript(redeemScript);
}
private List<ECKey> getMarriedKeysWithFollowed(DeterministicKey followedKey) {
ImmutableList.Builder<ECKey> keys = ImmutableList.builder();
List<ECKey> keys = new ArrayList<>();
for (DeterministicKeyChain keyChain : followingKeyChains) {
keyChain.maybeLookAhead();
keys.add(keyChain.getKeyByPath(followedKey.getPath()));
}
keys.add(followedKey);
return keys.build();
return Collections.unmodifiableList(keys);
}
/** Get the redeem data for a key in this married chain */

View file

@ -19,7 +19,6 @@ package org.bitcoinj.wallet;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@ -542,7 +541,7 @@ public class Wallet extends BaseTaggableObject
public List<TransactionSigner> getTransactionSigners() {
lock.lock();
try {
return ImmutableList.copyOf(signers);
return Collections.unmodifiableList(signers);
} finally {
lock.unlock();
}
@ -1041,7 +1040,7 @@ public class Wallet extends BaseTaggableObject
* @return true if successful
*/
public boolean removeWatchedAddress(final Address address) {
return removeWatchedAddresses(ImmutableList.of(address));
return removeWatchedAddresses(Collections.singletonList(address));
}
/**
@ -1903,7 +1902,7 @@ public class Wallet extends BaseTaggableObject
lock.lock();
try {
if (dependencies == null)
dependencies = ImmutableList.of();
dependencies = Collections.emptyList();
RiskAnalysis analysis = riskAnalyzer.create(this, tx, dependencies);
RiskAnalysis.Result result = analysis.analyze();
if (result != RiskAnalysis.Result.OK) {

View file

@ -17,7 +17,9 @@
package org.bitcoinj.tools;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bitcoinj.core.listeners.*;
@ -33,12 +35,10 @@ import org.bitcoinj.wallet.RiskAnalysis.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
public class WatchMempool {
private static final Logger log = LoggerFactory.getLogger(WatchMempool.class);
private static final NetworkParameters PARAMS = MainNetParams.get();
private static final ImmutableList<Transaction> NO_DEPS = ImmutableList.of();
private static final List<Transaction> NO_DEPS = Collections.emptyList();
private static final Map<String, Integer> counters = new HashMap<>();
private static final String TOTAL_KEY = "TOTAL";
private static final long START_MS = System.currentTimeMillis();

View file

@ -39,7 +39,6 @@ import org.bitcoinj.wallet.DeterministicSeed;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.io.BaseEncoding;
import com.google.common.io.Resources;
import com.google.protobuf.ByteString;
@ -93,6 +92,8 @@ import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@ -585,13 +586,13 @@ public class WalletTool implements Callable<Integer> {
}
String[] xpubkeys = xpubKeysStr.split(",");
ImmutableList.Builder<DeterministicKey> keys = ImmutableList.builder();
List<DeterministicKey> keys = new ArrayList<>();
for (String xpubkey : xpubkeys) {
keys.add(DeterministicKey.deserializeB58(null, xpubkey.trim(), params));
}
MarriedKeyChain chain = MarriedKeyChain.builder()
.random(new SecureRandom())
.followingKeys(keys.build())
.followingKeys(Collections.unmodifiableList(keys))
.build();
wallet.addAndActivateHDChain(chain);
}
@ -908,7 +909,7 @@ public class WalletTool implements Callable<Integer> {
// Send the payment
try {
// No refund address specified, no user-specified memo field.
PaymentProtocol.Ack ack = session.sendPayment(ImmutableList.of(req.tx), null, null).get();
PaymentProtocol.Ack ack = session.sendPayment(Collections.singletonList(req.tx), null, null).get();
wallet.commitTx(req.tx);
System.out.println("Memo from server: " + ack.getMemo());
} catch (ExecutionException e) {
@ -1106,8 +1107,8 @@ public class WalletTool implements Callable<Integer> {
if (seedStr != null) {
DeterministicSeed seed;
// Parse as mnemonic code.
final List<String> split = ImmutableList
.copyOf(Splitter.on(CharMatcher.anyOf(" :;,")).omitEmptyStrings().split(seedStr));
final List<String> split = Collections
.unmodifiableList(Splitter.on(CharMatcher.anyOf(" :;,")).omitEmptyStrings().splitToList(seedStr));
String passphrase = ""; // TODO allow user to specify a passphrase
seed = new DeterministicSeed(split, null, passphrase, creationTimeSecs);
try {