All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reandroid.dex.data.IntegerDataItemList Maven / Gradle / Ivy

/*
 *  Copyright (C) 2022 github.com/REAndroid
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.reandroid.dex.data;

import com.reandroid.dex.base.DexPositionAlign;
import com.reandroid.dex.key.Key;
import com.reandroid.dex.sections.SectionType;
import com.reandroid.utils.collection.ArrayIterator;
import com.reandroid.utils.collection.ArraySort;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Predicate;

public class IntegerDataItemList extends IntegerList implements Iterable{
    private final SectionType sectionType;
    private final int usageType;
    private T[] items;

    public IntegerDataItemList(SectionType sectionType, int usageType, DexPositionAlign positionAlign) {
        super(positionAlign);
        this.sectionType = sectionType;
        this.usageType = usageType;
    }

    public T addNew(Key key){
        T item = getOrCreateSection(sectionType).getOrCreate(key);
        add(item.getIdx());
        return item;
    }
    public T addNew(){
        T item = getOrCreateSection(sectionType).createItem();
        add(item.getIdx());
        return item;
    }
    public T getOrCreateAt(int index){
        T item = getItem(index);
        if(item == null){
            ensureSize(index + 1);
            item = getOrCreateSection(sectionType).createItem();
            put(index, item.getIdx());
            onChanged();
        }
        return item;
    }
    public void addNull(){
        add(0);
    }

    @Override
    public void removeSelf() {
        setItems(null);
        super.removeSelf();
    }

    public void remove(T item) {
        removeIf(t -> t == item);
    }
    public void removeIf(Predicate filter) {
        T[] items = this.items;
        if(items == null){
            return;
        }
        int length = items.length;
        boolean found = false;
        for(int i = 0; i < length; i++){
            T item = items[i];
            if(filter.test(item)){
                items[i] = null;
                found = true;
            }
        }
        if(found){
            removeNulls();
        }
    }
    void removeNulls() {
        T[] items = this.items;
        if(items == null || items.length == 0){
            setItems(null);
            return;
        }
        int length = items.length;
        int count = 0;
        for(int i = 0; i < length; i++){
            if(items[i] == null){
                count ++;
            }
        }
        if(count == 0){
            return;
        }
        T[] update = sectionType.getCreator()
                .newArrayInstance(length - count);
        int index = 0;
        for(int i  = 0; i < length; i++){
            T element = items[i];
            if(element != null){
                update[index] = element;
                index++;
            }
        }
        setItems(update);
    }
    @Override
    public Iterator iterator() {
        return ArrayIterator.of(items);
    }
    public T getItem(int i){
        if(i < 0){
            return null;
        }
        T[] items = this.items;
        if(items == null || i >= items.length){
            return null;
        }
        return items[i];
    }
    public T[] getItems() {
        return items;
    }
    public void setItems(T[] items){
        if(items == this.items){
            return;
        }
        if(isEmpty(items)){
            this.items = null;
            setSize(0);
            return;
        }
        int length = items.length;
        setSize(length, false);
        for(int i = 0; i < length; i++){
            T item = items[i];
            put(i, getData(item));
            updateUsage(item);
        }
        this.items = items;
    }
    public boolean isEmpty() {
        return isEmpty(this.items);
    }
    public boolean sort(Comparator comparator){
        T[] items = this.items;
        if(items == null || items.length < 2){
            return false;
        }
        boolean sorted = ArraySort.sort(items, comparator);
        if(sorted){
            setItems(items.clone());
        }
        return sorted;
    }
    private void updateUsage(T[] items){
        if(items == null){
            return;
        }
        for(T item : items){
            updateUsage(item);
        }
    }
    private void updateUsage(T item){
        if(item == null){
            return;
        }
        item.addUsageType(usageType);
    }

    @Override
    void onChanged() {
        super.onChanged();
        cacheItems();
    }

    @Override
    protected void onPreRefresh() {
        super.onPreRefresh();
        refreshItems();
    }

    private void refreshItems(){
        T[] items = this.items;
        if(isEmpty(items)){
            this.items = null;
            setSize(0);
            return;
        }
        int length = items.length;
        setSize(length, false);
        boolean found = false;
        for(int i = 0; i < length; i++){
            T item = items[i];
            if(item != null){
                item = item.getReplace();
                items[i] = item;
            }
            int data = getData(item);
            put(i, getData(item));
            if(data == 0) {
                items[i] = null;
                found = true;
            }
            updateUsage(item);
        }
        if(found){
            removeNulls();
        }
    }
    private int getData(T item){
        if(item == null){
            return 0;
        }
        return item.getIdx();
    }
    private void cacheItems(){
        items = getSectionItem(sectionType, toArray());
        updateUsage(items);
    }
    private boolean isEmpty(T[] items){
        if(items == null || items.length == 0){
            return true;
        }
        for(int i = 0; i < items.length; i++){
            if(items[i] != null){
                return false;
            }
        }
        return true;
    }
    @Override
    public int hashCode() {
        int hash = 1;
        int size = size();
        for(int i = 0; i < size; i++){
            hash = hash * 31;
            Object item = getItem(i);
            if(item != null){
                hash = hash + item.hashCode();
            }
        }
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj == this){
            return true;
        }
        if(obj == null || getClass() != obj.getClass()){
            return false;
        }
        IntegerDataItemList itemList = (IntegerDataItemList)obj;
        int size = size();
        if(size != itemList.size()){
            return false;
        }
        for(int i = 0; i < size; i++){
            Object item1 = getItem(i);
            Object item2 = itemList.getItem(i);
            if(!Objects.equals(item1, item2)){
                return false;
            }
        }
        return true;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy