问题
I have this code.
private static Map<Long, List<TimePitchValue>> alternativeMethod(AudioFormat audioformat,
List<ChunkDTO> listChunkDTO, long index, int sizeChunk) {
int numBytesPerSample = audioformat.getSampleSizeInBits() / 8;
int quantitySamples = sizeChunk / numBytesPerSample;
long baseTime = quantitySamples * index;
Map<Long, List<TimePitchValue>> mapListTimePitchValue = new LinkedHashMap<>();
for (int i = 0; i < quantitySamples; i++) {
int time = i;
List<TimePitchValue> listTimePitchValueWithTime = listChunkDTO.stream().map(chunkDTO -> {
int value = extractValue(chunkDTO.getChunk(), numBytesPerSample, time);
TimePitchValue timePitchValue = new TimePitchValue(chunkDTO.getPitch(), baseTime + time, value);
return timePitchValue;
}).collect(Collectors.toList());
listTimePitchValueWithTime.sort(Comparator.comparingInt(TimePitchValue::getValue).reversed());
mapListTimePitchValue.put(baseTime + time, listTimePitchValueWithTime);
}
return mapListTimePitchValue;
}
for each time
value a List<TimePitchValue>
is generated with the name listTimePitchValue
, and I want Associates the specified listTimePitchValue
with the specified baseTime + time
in mapListTimePitchValue
.
for support
private static int extractValue(byte[] bytesSamples, int numBytesPerSample, int time) {
byte[] bytesSingleNumber = Arrays.copyOfRange(bytesSamples, time * numBytesPerSample, (time + 1) * numBytesPerSample);
int value = numBytesPerSample == 2
? (Byte2IntLit(bytesSingleNumber[0], bytesSingleNumber[1]))
: (byte2intSmpl(bytesSingleNumber[0]));
return value;
}
public static int Byte2IntLit(byte Byte00, byte Byte08) {
return (((Byte08) << 8)
| ((Byte00 & 0xFF)));
}
public static int byte2intSmpl(byte theByte) {
return (short) (((theByte - 128) & 0xFF)
<< 8);
}
ChunkDTO
class
public class ChunkDTO {
private final byte[] chunk;
private final long index;
private final Integer pitch;
public ChunkDTO(byte[] chunk, long index, Integer pitch) {
this.chunk = chunk;
this.index = index;
this.pitch = pitch;
}
public byte[] getChunk() {
return chunk;
}
public long getIndex() {
return index;
}
public Integer getPitch() {
return pitch;
}
@Override
public String toString() {
return "ChunkDTO{" + "index=" + index + ", pitch=" + pitch
+ ", chunk.length=" + (chunk!=null?chunk.length:"null") +
'}';
}
@Override
public int hashCode() {
int hash = 5;
hash = 29 * hash + (int) (this.index ^ (this.index >>> 32));
hash = 29 * hash + Objects.hashCode(this.pitch);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ChunkDTO other = (ChunkDTO) obj;
if (this.index != other.index) {
return false;
}
if (!Objects.equals(this.pitch, other.pitch)) {
return false;
}
return true;
}
}
TimePitchValue
class
public class TimePitchValue {
private int pitch;
private long time;
private int value;
public TimePitchValue() {
}
public TimePitchValue(int pitch, long time, int value) {
this.time = time;
this.pitch = pitch;
this.value = value;
}
public int getPitch() {
return pitch;
}
public void setPitch(int pitch) {
this.pitch = pitch;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public String toString() {
int length = String.valueOf(value).length();
String stringValue = new String(new char[12 - length]).replace('\0', ' ') + value;
return "TimeNoteValue{"
+ ", value='" + stringValue + "'}";
}
@Override
public int hashCode() {
int hash = 7;
hash = 13 * hash + this.pitch;
hash = 13 * hash + (int) (this.time ^ (this.time >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TimePitchValue other = (TimePitchValue) obj;
if (this.pitch != other.pitch) {
return false;
}
if (this.time != other.time) {
return false;
}
return true;
}
}
The Question is, is it possible return a sorted Map<Long, List<TimePitchValue>>
from the IntStream
directly?
(without previously create Map<Long, List<TimePitchValue>> mapListTimePitchValue = new LinkedHashMap<>();
and later put mapListTimePitchValue.put(baseTime + time, listTimePitchValue);
)
回答1:
Does this work for you?
public static Map<Long, List<TimePitchValue>> alternativeMethodme(
AudioFormat audioformat, List<ChunkDTO> listChunkDTO,
long index, int sizeChunk) {
int numBytesPerSample = audioformat.getSampleSizeInBits() / 8;
int quantitySamples = sizeChunk / numBytesPerSample;
long baseTime = quantitySamples * index;
return IntStream.range(0, quantitySamples).boxed()
.collect(Collectors.toMap(time -> baseTime + time,
time -> listChunkDTO.stream()
.map(chunkDTO -> new TimePitchValue(
chunkDTO.getPitch(),
baseTime + time,
extractValue(
chunkDTO.getChunk(),
numBytesPerSample,
time)))
.sorted(Comparator.comparingInt(
TimePitchValue::getValue)
.reversed())
.collect(Collectors.toList()),
(a,b)->a,
LinkedHashMap::new));
}
I think I finally figure this out. I had to do some rearanging of methods and such.
Updated. I added the sort and returned the map as a LinkedHashMap
来源:https://stackoverflow.com/questions/61844376/returning-linkedhashmap-from-intstream-java-8