powered by simpleCommunicator - 2.0.38     © 2025 Programmizd 02
Форумы / Java [игнор отключен] [закрыт для гостей] / Java 8 - уже не совсем Java?
25 сообщений из 448, страница 5 из 18
Java 8 - уже не совсем Java?
    #39164770
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Со ссылкой на Хабр. Подсчёт слов по шаблонам BigData и фреймворком Spark.

https://habrahabr.ru/company/piter/blog/276675/
Код: java
1.
2.
3.
4.
sparkContext.textFile("hdfs://...")
            .flatMap(line => line.split(" "))
            .map(word => (word, 1)).reduceByKey(_ + _)
            .saveAsTextFile("hdfs://...")
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167546
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Копаю stream() в данный момент. Стало интересно можно ли решить подобную задачу:

Допустим есть некая сущность Entity, у нее есть свои поля, id, entityId, список версий и булен флаг active.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

      public static class Entity {
		String name;
		//номер версии
		int version;
		//все версии одной энтити имеют одинаковый entityId
		int entityId;
		//уникальный айди, все версии всх энтитис имеют различный айди
		int id;
		// только одна версия может быть active
		boolean active;
		//список версий
		List<Entity> versions = new ArrayList<>();
		public Entity(String name, int version, int entityId, int id, boolean active) {
			this.name = name;
			this.active = active;
			this.entityId = entityId;
			this.id = id;
			this.version = version;
		}
	}



Допустим есть сервис, в котором мне возвращается список таких энтитис(ну допустим из базы). Поля версии в этом списке не заполнены.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Example {

	private static List<Entity> getEntities() {
		List<Entity> entities = new ArrayList<>();
		// entityId = 1, активная
		Entity e = new Entity("A", 1, 1, 1, true);
		entities.add(e);
		// entityId = 1, неактивная
		e = new Entity("B", 2, 1, 2, false);
		entities.add(e);
		// entityId = 1, неактивная
		e = new Entity("C", 3, 1, 3, false);
		entities.add(e);
		// entityId = 2, активная
		e = new Entity("D", 1, 2, 4, true);
		entities.add(e);
		// entityId = 2, неактивная
		e = new Entity("E", 2, 2, 5, false);
		entities.add(e);
		// entityId = 3, активная
		e = new Entity("E", 1, 3, 6, true);
		entities.add(e);
		return entities;
	}
}



Мне надо сгруппировать их таким образом -
создать лист ентитис, в котором будут содержаться только активные, НО все неактивные для данного entitiesId должны попасть в список versions для активной сущности. Вот как это делается для java < 8

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
private static List<Entity> groupByVersionJava7(List<Entity> entities) {
		Map<Integer, Entity> map = new HashMap<>();
		// Active может быть только одна entity. Первый проход - инициализируем мапу
		for (Entity e : entities) {
			if (e.active) {
				map.put(e.entityId, e);
			}
		}
		// Второй проход - добавляем версии
		for (Entity e : entities) {
			if (!e.active) {
				map.get(e.entityId).versions.add(e);
			}
		}
		return new ArrayList<>(map.values());
	}



Можно ли это переписать красивее или оптимальнее на java 8 использую stream()?

Полный пример тут -
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Example {

	public static void main(String[] args) {
		List<Entity> entities = getEntities();
		entities  = groupByVersionJava7(entities);
		//entities = groupByVersionJava8(entities);???
	}

	private static List<Entity> groupByVersionJava7(List<Entity> entities) {
		Map<Integer, Entity> map = new HashMap<>();
		// Active может быть только одна entity. Первый проход - инициализируем мапу
		for (Entity e : entities) {
			if (e.active) {
				map.put(e.entityId, e);
			}
		}
		// Второй проход - добавляем версии
		for (Entity e : entities) {
			if (!e.active) {
				map.get(e.entityId).versions.add(e);
			}
		}
		return new ArrayList<>(map.values());
	}
	
	private static List<Entity> groupByVersionJava8(List<Entity> entities) {
		// enttities.stream() ???
		return null;
	}

	private static List<Entity> getEntities() {
		List<Entity> entities = new ArrayList<>();
		// entityId = 1, активная
		Entity e = new Entity("A", 1, 1, 1, true);
		entities.add(e);
		// entityId = 1, неактивная
		e = new Entity("B", 2, 1, 2, false);
		entities.add(e);
		// entityId = 1, неактивная
		e = new Entity("C", 3, 1, 3, false);
		entities.add(e);
		// entityId = 2, активная
		e = new Entity("D", 1, 2, 4, true);
		entities.add(e);
		// entityId = 2, неактивная
		e = new Entity("E", 2, 2, 5, false);
		entities.add(e);
		// entityId = 3, активная
		e = new Entity("E", 1, 3, 6, true);
		entities.add(e);
		return entities;
	}
	
	public static class Entity {
		String name;
		//имя версии
		int version;
		//все версии одной энтити имеют одинаковый entityId
		int entityId;
		//уникальный айди, все версии всх энтитис имеют различный айди
		int id;
		// только одна версия может быть active
		boolean active;
		//список версий
		List<Entity> versions = new ArrayList<>();
		public Entity(String name, int version, int entityId, int id, boolean active) {
			this.name = name;
			this.active = active;
			this.entityId = entityId;
			this.id = id;
			this.version = version;
		}
	}
}



Ваш вариант метода groupByVersionJava8?
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167635
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
private static java.util.List<Entity> groupByVersionJava8(java.util.List<Entity> entities) {
    java.util.Map<Integer, Entity> map = new java.util.HashMap<>();
    entities.stream().forEachOrdered(e -> {
        if (e.active) {
            map.put(e.entityId, e);
        } else {
            map.get(e.entityId).versions.add(e);
        }
    });
    return new java.util.ArrayList<>(map.values());
}
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167653
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник,

Никакой особой магии тут не получится реализовать. Всё то же самое:

Код: java
1.
2.
3.
4.
5.
6.
        Map<Integer, Entity> activeMap = entities.stream()
                .filter(e -> e.active)
                .collect(toMap(e -> e.entityId, e -> e));
        entities.stream()
                .filter(e -> !e.active)
                .forEach(e -> activeMap.get(e.entityId).versions.add(e));
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167654
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman,

Сначала отсортировать надо по e.active, иначе будет NPE
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167669
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczзабыл ник,

Никакой особой магии тут не получится реализовать. Всё то же самое:

Код: java
1.
2.
3.
4.
5.
6.
        Map<Integer, Entity> activeMap = entities.stream()
                .filter(e -> e.active)
                .collect(toMap(e -> e.entityId, e -> e));
        entities.stream()
                .filter(e -> !e.active)
                .forEach(e -> activeMap.get(e.entityId).versions.add(e));



Ага, вот и я как не крутил, так и не смог в один проход(красиво) сделать:)
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167682
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никАга, вот и я как не крутил, так и не смог в один проход(красиво) сделать:)
Думаю что можно сделать проще, но с полным перебором для поиска по id, вместо HashMap.
Ещё можно развить идею Usman, отсортировать по active и entityId, чтобы затем схлопнуть в одну итерацию.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167803
slaymsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Посоветуйте, с чего стоит начинать изучение Джава? При базовом знании HTML и CSS
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167816
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slaymskПосоветуйте, с чего стоит начинать изучение Джава? При базовом знании HTML и CSS
С английского языка. Если с ним всё в норме, то бери официальный Java Tutorial.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167847
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczslaymskПосоветуйте, с чего стоит начинать изучение Джава? При базовом знании HTML и CSS
С английского языка. Если с ним всё в норме, то бери официальный Java Tutorial.
слишком категорично, хотя, в целом, я поддерживаю )
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167853
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slaymsk,

на ютубе полно видеороликов
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167864
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никАга, вот и я как не крутил, так и не смог в один проход(красиво) сделать:)
Красиво не будет. Но вот однострочник, например:

Код: java
1.
2.
3.
4.
5.
        return entities.stream()
                .sorted(Comparator.comparing(e -> !e.active)) //Сортируем активные
                .collect(groupingBy(e -> e.entityId)).values().stream() //Группируем интересно можно ли применить reduce?
                .map(group -> group.get(0).setVersions(group.subList(1, group.size()))) //Берем первый элемент, который после сортировки гарантировано активный и устанавливаем версии, возвращая ссылку на активную сущность
                .collect(toList()); //Собираем в список



Единственное что пришлось добавить builder style setter
Код: java
1.
2.
3.
4.
       public Entity setVersions(List<Entity> entities) {
            this.versions.addAll(entities);
            return this;
       }


Ну, и код подразумевает обязательное наличие одной активной сущности для каждого id.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39167967
Фотография fixxer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник, ну как-то так:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
    private static Map<Integer, Entity> groupByVersionJava8(List<Entity> entities) {
        return entities.stream().collect(Collectors.groupingBy(Entity::getEntityId,
                Collector.of(
                        ActiveAndVersions::new,
                        ActiveAndVersions::addEntity,
                        ActiveAndVersions::merge,
                        ActiveAndVersions::finisher)
                ));
    }

    public static class ActiveAndVersions {
        private Entity active;
        private ArrayList<Entity> versions = new ArrayList<>();

        public ActiveAndVersions() {
        }

        public void addEntity(Entity e) {
            if (e.isActive()) {
                active = e;
            } else {
                versions.add(e);
            }
        }

        public ActiveAndVersions merge(ActiveAndVersions that) {
            if (this.active != null) {
                this.versions.addAll(that.versions);
                return this;
            } else {
                return that.merge(this);
            }
        }

        public Entity finisher() {
            active.versions = versions;
            return active;
        }
    }



геттер для entityId сделаете и из мапы значения достанете сами
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168076
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fixxerзабыл ник, ну как-то так:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
    private static Map<Integer, Entity> groupByVersionJava8(List<Entity> entities) {
        return entities.stream().collect(Collectors.groupingBy(Entity::getEntityId,
                Collector.of(
                        ActiveAndVersions::new,
                        ActiveAndVersions::addEntity,
                        ActiveAndVersions::merge,
                        ActiveAndVersions::finisher)
                ));
    }

    public static class ActiveAndVersions {
        private Entity active;
        private ArrayList<Entity> versions = new ArrayList<>();

        public ActiveAndVersions() {
        }

        public void addEntity(Entity e) {
            if (e.isActive()) {
                active = e;
            } else {
                versions.add(e);
            }
        }

        public ActiveAndVersions merge(ActiveAndVersions that) {
            if (this.active != null) {
                this.versions.addAll(that.versions);
                return this;
            } else {
                return that.merge(this);
            }
        }

        public Entity finisher() {
            active.versions = versions;
            return active;
        }
    }



геттер для entityId сделаете и из мапы значения достанете сами

Класс обертка не подходит по ряду причин, к сожалению. В основном из-за кривого юая, именно за этим и такой изврат с версиями, потому что на юай только одно новое поле обработать)
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168077
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczзабыл никАга, вот и я как не крутил, так и не смог в один проход(красиво) сделать:)
Красиво не будет. Но вот однострочник, например:

Код: java
1.
2.
3.
4.
5.
        return entities.stream()
                .sorted(Comparator.comparing(e -> !e.active)) //Сортируем активные
                .collect(groupingBy(e -> e.entityId)).values().stream() //Группируем интересно можно ли применить reduce?
                .map(group -> group.get(0).setVersions(group.subList(1, group.size()))) //Берем первый элемент, который после сортировки гарантировано активный и устанавливаем версии, возвращая ссылку на активную сущность
                .collect(toList()); //Собираем в список



Единственное что пришлось добавить builder style setter
Код: java
1.
2.
3.
4.
       public Entity setVersions(List<Entity> entities) {
            this.versions.addAll(entities);
            return this;
       }


Ну, и код подразумевает обязательное наличие одной активной сущности для каждого id.

Да, активная будет 100%. Интересно, а я вот и так и сяк групинг пробовал - но так ничего и не получилось. Вроде как и красиво все с этими стримами, но не интуитивно, надо обомозговать хорошо, в отличие от императивного стиля, взял да и заколбасил по ходу движения)
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168086
Фотография fixxer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никfixxer
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
    private static Map<Integer, Entity> groupByVersionJava8(List<Entity> entities) {
        return entities.stream().collect(Collectors.groupingBy(Entity::getEntityId,
                Collector.of(
                        ActiveAndVersions::new,
                        ActiveAndVersions::addEntity,
                        ActiveAndVersions::merge,
                        ActiveAndVersions::finisher)
                ));
    }

    public static class ActiveAndVersions {
        private Entity active;
        private ArrayList<Entity> versions = new ArrayList<>();

        public ActiveAndVersions() {
        }

        public void addEntity(Entity e) {
            if (e.isActive()) {
                active = e;
            } else {
                versions.add(e);
            }
        }

        public ActiveAndVersions merge(ActiveAndVersions that) {
            if (this.active != null) {
                this.versions.addAll(that.versions);
                return this;
            } else {
                return that.merge(this);
            }
        }

        public Entity finisher() {
            active.versions = versions;
            return active;
        }
    }




Класс обертка не подходит по ряду причин, к сожалению. В основном из-за кривого юая, именно за этим и такой изврат с версиями, потому что на юай только одно новое поле обработать)

Вы не поняли. Мутабельная обертка используется только для свертки, на входе и выходе все та же Entity.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168235
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никВроде как и красиво все с этими стримами, но не интуитивно, надо обомозговать хорошо, в отличие от императивного стиля, взял да и заколбасил по ходу движения)
А никто не обещает серебряной пули. Просто ещё один вариант. Нужно выбрать тот что проще и его реализовать.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168360
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дальше идёт моё сугубо личное ИМХО.

Новое - хорошо забытое старое. Давайте почитаем как определяет Streams документация по Scala

Цитирую
http://www.scala-lang.org/docu/files/collections-api/collections_14.html A Stream is like a list except that its elements are computed lazily.
Because of this, a stream can be infinitely long. Only those elements
requested are computed. Otherwise, streams have the same
performance characteristics as lists.
Обратите внимание на lazy computing. Еще цитата из JDK 8

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate
removal, can be implemented lazily, exposing opportunities for optimization. For
example, "find the first String with three consecutive vowels" need not examine
all the input strings. Stream operations are divided into intermediate (Stream-producing)
operations and terminal (value- or side-effect-producing) operations. Intermediate
operations are always lazy.

Я не помню где и когда были анонсированы ленивые вычисления. С точки зрения ФП
им уже 100 лет в обед. Историю создания Scala я не знаю но wiki пишет что с 2003 года.

В 2003 году был переход с J2SE 1.4 на J2SE 5. Никаких java.util.Stream еще не было.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168377
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЯ не помню где и когда были анонсированы ленивые вычисления. С точки зрения ФП
им уже 100 лет в обед. Историю создания Scala я не знаю но wiki пишет что с 2003 года.
В 2003 году был переход с J2SE 1.4 на J2SE 5. Никаких java.util.Stream еще не было.
Не очень понял к чему этот экскурс в историю. Подавляющее большинство концепций в программировании были описаны ещё в 70-х. В том числе ленивые вычисления.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168395
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К тому что стримы в Java нужно было вводить еще лет 10 назад.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168410
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonК тому что стримы в Java нужно было вводить еще лет 10 назад.
Люди, которые думали так же и реализовали Scala. :)
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168614
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так и старик Бьярне. Сидит в своих кедах, закинув ноги на стол и думает.
Внести ли в новую спеку С++ то о чём долго говорят большевики.... ? Или нет?
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168646
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не могу больше найти ссылку. На прошлой неделе видел её в Java дайджесте на dou.ua. Там был отличный вопрос "как реализовать такое на стримах", на который, кажется Getz ответил. Но позже твит, вроде удалили. Как раз там пример близкий к этому топику о том как не надо писать в функциональном стиле на Java.
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168739
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz
Код: java
1.
2.
3.
4.
5.
        return entities.stream()
                .sorted(Comparator.comparing(e -> !e.active)) //Сортируем активные
                .collect(groupingBy(e -> e.entityId)).values().stream() //Группируем интересно можно ли применить reduce?
                .map(group -> group.get(0).setVersions(group.subList(1, group.size()))) //Берем первый элемент, который после сортировки гарантировано активный и устанавливаем версии, возвращая ссылку на активную сущность
                .collect(toList()); //Собираем в список




Написал тест, у этого кода есть один косяк. Он будет работать только если обьявить versions как Set. Дело в том, что в setVersions() будет передаваться каждая группа. Простейший случай - 3 энтити(айди по порядку), первая активная. Тогда сначала в версии добавится id=2, а потом id=2 и id=3. Понятнее говоря, после выполнения в версиях будет две версии с id=2 и одна с айди =3
...
Рейтинг: 0 / 0
Java 8 - уже не совсем Java?
    #39168746
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник Дело в том, что в setVersions() будет передаваться каждая группа. Простейший случай - 3 энтити(айди по порядку), первая активная. Тогда сначала в версии добавится id=2, а потом id=2 и id=3.

Тут фигню написал, поставил брейкпоинт в setVersions, почему то туда сразу 3 entites пришло, две из них с одинаковым айди. Дебажить stream тоже то еще удовольствие:)
...
Рейтинг: 0 / 0
25 сообщений из 448, страница 5 из 18
Форумы / Java [игнор отключен] [закрыт для гостей] / Java 8 - уже не совсем Java?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]