mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-30 14:24:25 +02:00
V1.0.2
This commit is contained in:
parent
bf310c0cac
commit
3dbd9a1e2c
@ -142,4 +142,47 @@ public class ByteArray extends BlockItem {
|
||||
public String toString(){
|
||||
return "size="+size();
|
||||
}
|
||||
|
||||
public static byte[] trimTrailZeros(byte[] bts){
|
||||
if(bts==null){
|
||||
return new byte[0];
|
||||
}
|
||||
int len=0;
|
||||
for(int i=0;i<bts.length;i++){
|
||||
if(bts[i]!=0){
|
||||
len=i+1;
|
||||
}
|
||||
}
|
||||
byte[] result=new byte[len];
|
||||
if(result.length>0){
|
||||
System.arraycopy(bts, 0, result, 0, result.length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public static boolean equals(byte[] bts1, byte[] bts2){
|
||||
if(bts1==bts2){
|
||||
return true;
|
||||
}
|
||||
if(bts1==null || bts1.length==0){
|
||||
return bts2==null || bts2.length==0;
|
||||
}
|
||||
if(bts2==null || bts2.length==0){
|
||||
return false;
|
||||
}
|
||||
if(bts1.length!=bts2.length){
|
||||
return false;
|
||||
}
|
||||
for(int i=0;i<bts1.length;i++){
|
||||
if(bts1[i]!=bts2[i]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static boolean equalsIgnoreTrailZero(byte[] bts1, byte[] bts2){
|
||||
if(bts1==bts2){
|
||||
return true;
|
||||
}
|
||||
return equals(trimTrailZeros(bts1), trimTrailZeros(bts2));
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,90 @@ public class EntryBlock extends Block{
|
||||
super();
|
||||
}
|
||||
|
||||
public ResValueInt setValueAsBoolean(boolean val){
|
||||
ResValueInt resValueInt;
|
||||
BaseResValue res = getResValue();
|
||||
if(res instanceof ResValueInt){
|
||||
resValueInt=(ResValueInt) res;
|
||||
}else {
|
||||
resValueInt=new ResValueInt();
|
||||
setResValue(resValueInt);
|
||||
}
|
||||
resValueInt.setType(ValueType.INT_BOOLEAN);
|
||||
resValueInt.setData(val?0xffffffff:0);
|
||||
return resValueInt;
|
||||
}
|
||||
public ResValueInt setValueAsInteger(int val){
|
||||
ResValueInt resValueInt;
|
||||
BaseResValue res = getResValue();
|
||||
if(res instanceof ResValueInt){
|
||||
resValueInt=(ResValueInt) res;
|
||||
}else {
|
||||
resValueInt=new ResValueInt();
|
||||
setResValue(resValueInt);
|
||||
}
|
||||
resValueInt.setType(ValueType.INT_DEC);
|
||||
resValueInt.setData(val);
|
||||
return resValueInt;
|
||||
}
|
||||
public ResValueInt setValueAsReference(int resId){
|
||||
ResValueInt resValueInt;
|
||||
BaseResValue res = getResValue();
|
||||
if(res instanceof ResValueInt){
|
||||
resValueInt=(ResValueInt) res;
|
||||
}else {
|
||||
resValueInt=new ResValueInt();
|
||||
setResValue(resValueInt);
|
||||
}
|
||||
resValueInt.setType(ValueType.REFERENCE);
|
||||
resValueInt.setData(resId);
|
||||
return resValueInt;
|
||||
}
|
||||
public ResValueInt setValueAsString(String str){
|
||||
TableStringPool stringPool=getTableStringPool();
|
||||
if(stringPool==null){
|
||||
throw new IllegalArgumentException("TableStringPool = null, EntryBlock not added to parent TableBlock");
|
||||
}
|
||||
TableString tableString = stringPool.getOrCreate(str);
|
||||
ResValueInt resValueInt;
|
||||
BaseResValue res = getResValue();
|
||||
if(res instanceof ResValueInt){
|
||||
resValueInt=(ResValueInt) res;
|
||||
}else {
|
||||
resValueInt=new ResValueInt();
|
||||
setResValue(resValueInt);
|
||||
}
|
||||
resValueInt.setType(ValueType.STRING);
|
||||
resValueInt.setData(tableString.getIndex());
|
||||
return resValueInt;
|
||||
}
|
||||
public String getValueAsString(){
|
||||
TableStringPool stringPool=getTableStringPool();
|
||||
if(stringPool==null){
|
||||
return null;
|
||||
}
|
||||
BaseResValue res = getResValue();
|
||||
if(!(res instanceof ResValueInt)){
|
||||
return null;
|
||||
}
|
||||
ResValueInt resValueInt=(ResValueInt)res;
|
||||
TableString tableString= stringPool.get(resValueInt.getData());
|
||||
if(tableString==null){
|
||||
return null;
|
||||
}
|
||||
return tableString.getHtml();
|
||||
}
|
||||
private TableStringPool getTableStringPool(){
|
||||
PackageBlock pkg=getPackageBlock();
|
||||
if(pkg==null){
|
||||
return null;
|
||||
}
|
||||
TableBlock table = pkg.getTableBlock();
|
||||
if(table==null){
|
||||
return null;
|
||||
}
|
||||
return table.getTableStringPool();
|
||||
}
|
||||
public boolean isDefault(){
|
||||
TypeBlock typeBlock=getTypeBlock();
|
||||
if(typeBlock!=null){
|
||||
@ -329,8 +413,6 @@ public class EntryBlock extends Block{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void unlockEntry(){
|
||||
if(mUnLocked){
|
||||
return;
|
||||
@ -375,16 +457,6 @@ public class EntryBlock extends Block{
|
||||
mResValue=null;
|
||||
}
|
||||
}
|
||||
private void refreshResValue(){
|
||||
if(mResValue==null){
|
||||
return;
|
||||
}
|
||||
if(isFlagsComplex()==(mResValue instanceof ResValueBag)){
|
||||
return;
|
||||
}
|
||||
removeResValue();
|
||||
createResValue();
|
||||
}
|
||||
private void refreshHeaderSize(){
|
||||
if(isFlagsComplex()){
|
||||
mHeaderSize.set(HEADER_COMPLEX);
|
||||
@ -404,11 +476,9 @@ public class EntryBlock extends Block{
|
||||
}
|
||||
setResValueInternal(resValue);
|
||||
}
|
||||
|
||||
private boolean isFlagsComplex(){
|
||||
return ((mFlags.get() & FLAG_COMPLEX_MASK) != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNull(boolean is_null){
|
||||
if(is_null){
|
||||
|
@ -8,6 +8,8 @@ import com.reandroid.lib.arsc.item.ByteArray;
|
||||
import com.reandroid.lib.arsc.item.IntegerItem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
|
||||
@ -47,12 +49,14 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
mQualifiers=null;
|
||||
}
|
||||
public void setConfigSize(int size){
|
||||
if(size != SIZE_28
|
||||
if( size != SIZE_16
|
||||
&& size != SIZE_28
|
||||
&& size != SIZE_32
|
||||
&& size != SIZE_36
|
||||
&& size != SIZE_48
|
||||
&& size != SIZE_56
|
||||
&& size != SIZE_64){
|
||||
&& size != SIZE_64
|
||||
){
|
||||
throw new IllegalArgumentException("Invalid config size = " + size);
|
||||
}
|
||||
this.configSize.set(size);
|
||||
@ -63,28 +67,93 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
public int getConfigSize(){
|
||||
return this.configSize.get();
|
||||
}
|
||||
public boolean trimToSize(int size){
|
||||
int current=getConfigSize();
|
||||
if(current==size){
|
||||
return true;
|
||||
}
|
||||
if( size != SIZE_16
|
||||
&& size != SIZE_28
|
||||
&& size != SIZE_32
|
||||
&& size != SIZE_36
|
||||
&& size != SIZE_48
|
||||
&& size != SIZE_56
|
||||
&& size != SIZE_64
|
||||
){
|
||||
return false;
|
||||
}
|
||||
if(current<size){
|
||||
setConfigSize(size);
|
||||
return true;
|
||||
}
|
||||
int offset=size-4;
|
||||
int len=current-4-offset;
|
||||
byte[] bts=mValuesContainer.getByteArray(offset, len);
|
||||
if(!isNull(bts)){
|
||||
return false;
|
||||
}
|
||||
setConfigSize(size);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setMcc(short sh){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(sh==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set mcc for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.putShort(OFFSET_mcc, sh);
|
||||
}
|
||||
public short getMcc(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.getShort(OFFSET_mcc);
|
||||
}
|
||||
public void setMnc(short sh){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(sh==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set mnc for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.putShort(OFFSET_mnc, sh);
|
||||
}
|
||||
public short getMnc(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.getShort(OFFSET_mnc);
|
||||
}
|
||||
public void setLanguageIn0(byte b){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set languageIn0 for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_languageIn0, b);
|
||||
}
|
||||
public byte getLanguageIn0(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_languageIn0);
|
||||
}
|
||||
public void setLanguageIn1(byte b){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set languageIn1 for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_languageIn1, b);
|
||||
}
|
||||
public byte getLanguageIn1(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_languageIn1);
|
||||
}
|
||||
public char[] getLanguage(){
|
||||
@ -103,15 +172,33 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
setLanguageIn1(bts[1]);
|
||||
}
|
||||
public void setCountryIn0(byte b){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set countryIn0 for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_countryIn0, b);
|
||||
}
|
||||
public byte getCountryIn0(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_countryIn0);
|
||||
}
|
||||
public void setCountryIn1(byte b){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set countryIn1 for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_countryIn1, b);
|
||||
}
|
||||
public byte getCountryIn1(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_countryIn1);
|
||||
}
|
||||
public char[] getRegion(){
|
||||
@ -130,57 +217,138 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
setCountryIn1(bts[1]);
|
||||
}
|
||||
public void setOrientation(byte b){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set orientation for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_orientation, b);
|
||||
}
|
||||
public byte getOrientation(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_orientation);
|
||||
}
|
||||
public void setTouchscreen(byte b){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set touchscreen for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_touchscreen, b);
|
||||
}
|
||||
public byte getTouchscreen(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_touchscreen);
|
||||
}
|
||||
public void setDensity(short sh){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
if(sh==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set density for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.putShort(OFFSET_density, sh);
|
||||
}
|
||||
public short getDensity(){
|
||||
if(getConfigSize()<SIZE_16){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.getShort(OFFSET_density);
|
||||
}
|
||||
public void setKeyboard(byte b){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set keyboard for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_keyboard, b);
|
||||
}
|
||||
public byte getKeyboard(){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_keyboard);
|
||||
}
|
||||
public void setNavigation(byte b){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set navigation for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_navigation, b);
|
||||
}
|
||||
public byte getNavigation(){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_navigation);
|
||||
}
|
||||
public void setInputFlags(byte b){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set inputFlags for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_inputFlags, b);
|
||||
}
|
||||
public byte getInputFlags(){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_inputFlags);
|
||||
}
|
||||
public void setInputPad0(byte b){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
if(b==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set inputPad0 for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.put(OFFSET_inputPad0, b);
|
||||
}
|
||||
public byte setInputPad0(){
|
||||
public byte getInputPad0(){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.get(OFFSET_inputPad0);
|
||||
}
|
||||
public void setScreenWidth(short sh){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
if(sh==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set screenWidth for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.putShort(OFFSET_screenWidth, sh);
|
||||
}
|
||||
public short getScreenWidth(){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.getShort(OFFSET_screenWidth);
|
||||
}
|
||||
public void setScreenHeight(short sh){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
if(sh==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set screenHeight for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.putShort(OFFSET_screenHeight, sh);
|
||||
}
|
||||
public short getScreenHeight(){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.getShort(OFFSET_screenHeight);
|
||||
}
|
||||
public void setScreenSize(short w, short h){
|
||||
@ -188,15 +356,33 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
this.setScreenHeight(h);
|
||||
}
|
||||
public void setSdkVersion(short sh){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
if(sh==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set sdkVersion for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.putShort(OFFSET_sdkVersion, sh);
|
||||
}
|
||||
public short getSdkVersion(){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.getShort(OFFSET_sdkVersion);
|
||||
}
|
||||
public void setMinorVersion(short sh){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
if(sh==0){
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Can not set minorVersion for config size="+getConfigSize());
|
||||
}
|
||||
mValuesContainer.putShort(OFFSET_minorVersion, sh);
|
||||
}
|
||||
public short getMinorVersion(){
|
||||
if(getConfigSize()<SIZE_28){
|
||||
return 0;
|
||||
}
|
||||
return mValuesContainer.getShort(OFFSET_minorVersion);
|
||||
}
|
||||
public void setScreenLayout(byte b){
|
||||
@ -347,18 +533,17 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
return mValuesContainer.get(OFFSET_colorMode);
|
||||
}
|
||||
|
||||
private void valuesChanged(int val, int old){
|
||||
if(val==old){
|
||||
return;
|
||||
}
|
||||
valuesChanged();
|
||||
}
|
||||
private void valuesChanged(){
|
||||
mQualifiers=null;
|
||||
}
|
||||
|
||||
public String getQualifiers(){
|
||||
if(mQualifiers==null){
|
||||
mQualifiers = ResConfigHelper.toQualifier(this).trim();
|
||||
try{
|
||||
mQualifiers = ResConfigHelper.toQualifier(this).trim();
|
||||
}catch (Exception ex){
|
||||
mQualifiers = "";
|
||||
}
|
||||
}
|
||||
return mQualifiers;
|
||||
}
|
||||
@ -374,13 +559,26 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
return ResConfigHelper.decodeLocale(this);
|
||||
}
|
||||
public boolean isDefault(){
|
||||
return getQualifiers().length()==0;
|
||||
return isNull(mValuesContainer.getBytes());
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
if(o instanceof ResConfig){
|
||||
ResConfig config=(ResConfig)o;
|
||||
return getQualifiers().equals(config.getQualifiers());
|
||||
public int hashCode(){
|
||||
byte[] bts = ByteArray.trimTrailZeros(mValuesContainer.getBytes());
|
||||
return Arrays.hashCode(bts);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
if(obj==this){
|
||||
return true;
|
||||
}
|
||||
if(obj==null){
|
||||
return false;
|
||||
}
|
||||
if(obj instanceof ResConfig){
|
||||
ResConfig other = (ResConfig)obj;
|
||||
byte[] bts1 = mValuesContainer.getBytes();
|
||||
byte[] bts2 = other.mValuesContainer.getBytes();
|
||||
return ByteArray.equalsIgnoreTrailZero(bts1, bts2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -509,12 +707,13 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final int SIZE_28 = 28;
|
||||
private static final int SIZE_32 = 32;
|
||||
private static final int SIZE_36 = 36;
|
||||
private static final int SIZE_48 = 48;
|
||||
private static final int SIZE_56 = 56;
|
||||
private static final int SIZE_64 = 64;
|
||||
public static final int SIZE_16 = 16;
|
||||
public static final int SIZE_28 = 28;
|
||||
public static final int SIZE_32 = 32;
|
||||
public static final int SIZE_36 = 36;
|
||||
public static final int SIZE_48 = 48;
|
||||
public static final int SIZE_56 = 56;
|
||||
public static final int SIZE_64 = 64;
|
||||
|
||||
private static final int OFFSET_mcc = 0;
|
||||
private static final int OFFSET_mnc = 2;
|
||||
@ -525,6 +724,7 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad {
|
||||
private static final int OFFSET_orientation = 8;
|
||||
private static final int OFFSET_touchscreen = 9;
|
||||
private static final int OFFSET_density = 10;
|
||||
//SIZE=16
|
||||
private static final int OFFSET_keyboard = 12;
|
||||
private static final int OFFSET_navigation = 13;
|
||||
private static final int OFFSET_inputFlags = 14;
|
||||
|
@ -9,7 +9,7 @@ import java.util.regex.Pattern;
|
||||
public class ResConfigHelper {
|
||||
public static ResConfig fromQualifiers(String qualifiers){
|
||||
ResConfig result=new ResConfig();
|
||||
result.setConfigSize(64);
|
||||
result.setConfigSize(ResConfig.SIZE_64);
|
||||
parseQualifiers(result, qualifiers);
|
||||
return result;
|
||||
}
|
||||
@ -52,15 +52,13 @@ public class ResConfigHelper {
|
||||
if(isNull(split)){
|
||||
return qualifiers;
|
||||
}
|
||||
int len=split.length;
|
||||
Set<String> qSet=new HashSet<>();
|
||||
for(int i=0; i<len;i++){
|
||||
List<String> qList=new ArrayList<>();
|
||||
for(int i=0;i<split.length;i++){
|
||||
String q=split[i];
|
||||
if(q!=null){
|
||||
qSet.add(q);
|
||||
if(q!=null && !qList.contains(q)){
|
||||
qList.add(q);
|
||||
}
|
||||
}
|
||||
List<String> qList=new ArrayList<>(qSet);
|
||||
Comparator<String> cmp=new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String s1, String s2) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user