package com.lonely.数组;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
public class MyArray<T> {
private T[] data;
private int size;
public MyArray() {
this(10);
}
public MyArray(int capcity) {
if (capcity >= 0) {
this.data = (T[]) new Object[capcity];
} else {
throw new IllegalArgumentException(MessageFormat.format("数组构建函数中初始化容量:{0}不能小于0", capcity));
}
}
public int getSize() {
return size;
}
public int getCapcity() {
return this.data.length;
}
public boolean isEmpty() {
return size == 0;
}
public boolean addLast(T t) {
return this.add(getSize(), t);
}
public boolean addFirst(T t) {
return this.add(0, t);
}
public boolean add(int index, T t) {
if (whetherExpansionIsNeeded()) {
resize(2 * getCapcity());
}
if (index < 0 || index >= getCapcity()) {
throw new IndexOutOfBoundsException(MessageFormat.format("下标:{0}越界,不在范围({1}~{2})中", index, 0, getSize()));
}
for (int i = getSize(); i > index; i--) {
this.data[i + 1] = this.data[i];
}
this.data[index] = t;
this.size++;
return true;
}
public T getFirst() {
return this.get(0);
}
public T getLast() {
return this.get(getSize() - 1);
}
public T get(int index) {
whetherTheSubscriptCrossesTheBoundary(index);
return this.data[index];
}
public void set(int index, T newData) {
whetherTheSubscriptCrossesTheBoundary(index);
this.data[index] = newData;
}
public boolean container(T t) {
for (int i = 0; i < getSize(); i++) {
if (this.data[i].equals(t)) {
return true;
}
}
return false;
}
public int find(T t) {
for (int i = 0; i < getSize(); i++) {
if (this.data[i].equals(t)) {
return i;
}
}
return -1;
}
public Integer[] findAll(T t) {
final int groupSize = getSize() % 10 == 0 ? getSize() / 10 : getSize() / 10 + 1;
final Map<Integer, List<T>> groupMap = new HashMap<>();
for (int i = 0; i < getSize(); i++) {
int currGroup = i / 10 + 1;
if (groupMap.containsKey(currGroup)) {
groupMap.get(currGroup).add(this.data[i]);
} else {
List<T> list = new ArrayList<>();
list.add(this.data[i]);
groupMap.put(currGroup, list);
}
}
ExecutorService pool = new ThreadPoolExecutor(groupSize, 2 * groupSize, 1000, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
Map<Integer, List<Integer>> indexGroupMap = new HashMap<>();
for (int i = 1; i <= groupSize; i++) {
final int index = i;
final T newT = t;
try {
indexGroupMap.put(i, pool.submit(() -> {
List<Integer> indexs = new ArrayList<>();
List<T> datas = groupMap.get(index);
for (int j = 0; j < datas.size(); j++) {
if (datas.get(j).equals(newT)) {
indexs.add(j + (index - 1) * 10);
}
}
return indexs;
}).get());
} catch (Exception e) {
e.printStackTrace();
}
}
try {
pool.shutdown();
if (!pool.awaitTermination(5 * 1000, TimeUnit.MILLISECONDS)) {
pool.shutdownNow();
}
} catch (InterruptedException e) {
e.printStackTrace();
pool.shutdownNow();
}
List<Integer> indexList = new ArrayList<>();
for (int i = 1; i <= groupSize; i++) {
if (indexGroupMap.containsKey(i)) {
List<Integer> integers = indexGroupMap.get(i);
if (integers != null && integers.size() > 0) {
indexList.addAll(integers);
}
}
}
return indexList.toArray(new Integer[0]);
}
public T remove(int index) {
whetherTheSubscriptCrossesTheBoundary(index);
T removeElement = this.data[index];
for (int i = index; i < getSize() - 1; i++) {
this.data[i] = this.data[i + 1];
}
size--;
if (size <= getCapcity() / 2) {
resize(getCapcity() / 2);
}
return removeElement;
}
public T removeFirst() {
return this.remove(0);
}
public T removeLast() {
return this.remove(getSize() - 1);
}
public void removeElement(T t) {
int i = this.find(t);
if (i != -1) {
this.remove(i);
}
}
public void batchRemoveElement(T t) {
Integer[] allIndexs = this.findAll(t);
if (allIndexs != null && allIndexs.length > 0) {
for (int i = 0; i < allIndexs.length; i++) {
this.remove(allIndexs[i]);
}
}
}
@Override
public String toString() {
StringBuilder message = new StringBuilder("[");
for (int i = 0; i < getSize(); i++) {
if (i == getSize() - 1) {
message.append(this.data[i]);
} else {
message.append(this.data[i]).append(",");
}
}
message.append("]");
return message.toString();
}
private boolean whetherExpansionIsNeeded() {
return getSize() == getCapcity();
}
private void resize(int newCapcity) {
T[] newData = (T[]) new Object[newCapcity];
for (int i = 0; i < getSize(); i++) {
newData[i] = this.data[i];
}
this.data = newData;
}
private void whetherTheSubscriptCrossesTheBoundary(int index) {
if (index < 0 || index >= getSize()) {
throw new IndexOutOfBoundsException(MessageFormat.format("下标:{0}越界,不在范围({1}~{2})中", index, 0, getSize()));
}
}
}